mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
mpm: comment out functionality to make it work
- add uio udev find routine - add debug prints Signed-off-by: Andrej Rode <andrej.rode@ettus.com> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
This commit is contained in:
parent
f27cb2a771
commit
7f71111988
@ -24,6 +24,7 @@ SET(USRP_MPM_TOP_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/types.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/discovery.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/uio.py
|
||||
)
|
||||
LIST(APPEND USRP_MPM_FILES ${USRP_MPM_TOP_FILES})
|
||||
ADD_SUBDIRECTORY(periph_manager)
|
||||
|
||||
@ -21,7 +21,7 @@ Mboard implementation base class
|
||||
import os
|
||||
from ..types import EEPROM
|
||||
from .. import dboard_manager
|
||||
from .udev import get_eeprom
|
||||
from .udev import get_eeprom_path
|
||||
from .udev import get_spidev_nodes
|
||||
from six import iteritems
|
||||
|
||||
@ -44,17 +44,20 @@ class PeriphManagerBase(object):
|
||||
dboard_eeprom_addrs = {}
|
||||
dboard_spimaster_addrs = {}
|
||||
updateable_components = []
|
||||
sid_endpoints = {}
|
||||
available_endpoints = range(256)
|
||||
|
||||
def __init__(self):
|
||||
# I know my EEPROM address, lets use it
|
||||
self.overlays = ""
|
||||
(self._eeprom_head, self._eeprom_rawdata) = EEPROM().read_eeprom(
|
||||
get_eeprom(self.mboard_eeprom_addr))
|
||||
get_eeprom_path(self.mboard_eeprom_addr))
|
||||
print self._eeprom_head
|
||||
self._dboard_eeproms = {}
|
||||
for dboard_slot, eeprom_addr in self.dboard_eeprom_addrs.iteritems():
|
||||
spi_devices = []
|
||||
# I know EEPROM adresses for my dboard slots
|
||||
eeprom_data = EEPROM().read_eeprom(get_eeprom(eeprom_addr))
|
||||
eeprom_data = EEPROM().read_eeprom(get_eeprom_path(eeprom_addr))
|
||||
# I know spidev masters on the dboard slots
|
||||
hw_pid = eeprom_data[0].get("hw_pid", 0)
|
||||
if hw_pid in dboard_manager.HW_PIDS:
|
||||
@ -116,7 +119,7 @@ class PeriphManagerBase(object):
|
||||
# Init dboards
|
||||
pass
|
||||
|
||||
def _probe_interface(self, sender_addr):
|
||||
def _allocate_sid(self, sender_addr, sid, xbar_src_addr, xbar_src_port):
|
||||
"""
|
||||
Overload this method in actual device implementation
|
||||
"""
|
||||
@ -127,4 +130,3 @@ class PeriphManagerBase(object):
|
||||
Overload this method in actual device implementation
|
||||
"""
|
||||
return []
|
||||
|
||||
|
||||
@ -23,7 +23,13 @@ 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 .. import libpyusrp_periphs as lib
|
||||
from logging import getLogger
|
||||
import netaddr
|
||||
import socket
|
||||
|
||||
LOG = getLogger(__name__)
|
||||
|
||||
@ -34,9 +40,9 @@ class n310(PeriphManagerBase):
|
||||
"""
|
||||
hw_pids = "1"
|
||||
mboard_type = "n310"
|
||||
mboard_eeprom_addr = "e0007000.spi:ec@0:i2c-tunnel"
|
||||
dboard_eeprom_addrs = {"A": "something", "B": "else"}
|
||||
dboard_spimaster_addrs = {"A": "something", "B": "else"}
|
||||
mboard_eeprom_addr = "e0005000.i2c"
|
||||
# dboard_eeprom_addrs = {"A": "something", "B": "else"}
|
||||
# dboard_spimaster_addrs = {"A": "something", "B": "else"}
|
||||
interfaces = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -44,21 +50,22 @@ class n310(PeriphManagerBase):
|
||||
super(n310, self).__init__(*args, **kwargs)
|
||||
data = self._read_eeprom_v1(self._eeprom_rawdata)
|
||||
# mac 0: mgmt port, mac1: sfp0, mac2: sfp1
|
||||
self.interfaces["mgmt"] = {
|
||||
"mac_addr": byte_to_mac(data[0]),
|
||||
"addrs": get_iface_addrs(byte_to_mac(data[0]))
|
||||
}
|
||||
self.interfaces["sfp0"] = {
|
||||
"mac_addr": byte_to_mac(data[1]),
|
||||
"addrs": get_iface_addrs(byte_to_mac(data[1]))
|
||||
}
|
||||
self.interfaces["sfp1"] = {
|
||||
"mac_addr": byte_to_mac(data[2]),
|
||||
"addrs": get_iface_addrs(byte_to_mac(data[2]))
|
||||
}
|
||||
self.mboard_info["serial"] = data[3] # some format
|
||||
# self.interfaces["mgmt"] = {
|
||||
# "mac_addr": byte_to_mac(data[0]),
|
||||
# "addrs": get_iface_addrs(byte_to_mac(data[0]))
|
||||
# }
|
||||
# self.interfaces["sfp0"] = {
|
||||
# "mac_addr": byte_to_mac(data[1]),
|
||||
# "addrs": get_iface_addrs(byte_to_mac(data[1]))
|
||||
# }
|
||||
# self.interfaces["sfp1"] = {
|
||||
# "mac_addr": byte_to_mac(data[2]),
|
||||
# "addrs": get_iface_addrs(byte_to_mac(data[2]))
|
||||
# }
|
||||
self.mboard_info["serial"] = data[0] # some format
|
||||
with open("/sys/class/rfnoc_crossbar/crossbar0/local_addr", "w") as xbar:
|
||||
xbar.write("0x2")
|
||||
|
||||
print(data)
|
||||
# if header.get("dataversion", 0) == 1:
|
||||
|
||||
|
||||
@ -66,15 +73,17 @@ class n310(PeriphManagerBase):
|
||||
"""
|
||||
read eeprom with data version 1
|
||||
"""
|
||||
# data_version contains
|
||||
# data contains
|
||||
# 24 bytes header -> ignore them here
|
||||
# 8 bytes serial
|
||||
# 6 bytes mac_addr0
|
||||
# 2 bytes pad
|
||||
# 6 bytes mac_addr1
|
||||
# 2 bytes pad
|
||||
# 6 bytes mac_addr2
|
||||
# 2 bytes pad
|
||||
# 8 bytes serial
|
||||
return struct.unpack_from("6s 2x 6s 2x 6s 2x 8s", data)
|
||||
# 4 bytes CRC
|
||||
return struct.unpack_from("!28x 8s 6s 2x 6s 2x 6s 2x I", data)
|
||||
|
||||
def get_interfaces(self):
|
||||
"""
|
||||
@ -89,15 +98,40 @@ class n310(PeriphManagerBase):
|
||||
"""
|
||||
return self.interfaces.get(interface, {}).get("addrs", [])
|
||||
|
||||
def _probe_interface(self, sender_addr):
|
||||
def _allocate_sid(self, sender_addr, port, sid, xbar_src_addr, xbar_src_port):
|
||||
"""
|
||||
Get the MAC address of the sender and store it in the FPGA ARP table
|
||||
"""
|
||||
mac_addr = get_mac_addr(sender_addr)
|
||||
new_ep = self.available_endpoints.pop(0)
|
||||
if mac_addr is not None:
|
||||
# Do something with mac_address
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if sender_addr not in self.sid_endpoints:
|
||||
self.sid_endpoints.update({sender_addr: (new_ep,)})
|
||||
else:
|
||||
current_allocation = self.sid_endpoints.get(sender_addr)
|
||||
new_allocation = current_allocation + (new_ep,)
|
||||
self.sid_endpoints.update({sender_addr: new_allocation})
|
||||
sid = SID(sid)
|
||||
sid.set_src_addr(xbar_src_addr)
|
||||
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
|
||||
LOG.debug("got uio_path and size")
|
||||
uio_obj = uio(uio_path, uio_size, read_only=False)
|
||||
LOG.info("got my uio")
|
||||
LOG.info("ip_addr: %s", sender_addr)
|
||||
# LOG.info("mac_addr: %s", mac_addr)
|
||||
ip_addr = int(netaddr.IPAddress(sender_addr))
|
||||
mac_addr = int(netaddr.EUI(mac_addr))
|
||||
uio_obj.poke32(0x1000 + 4*new_ep, ip_addr)
|
||||
print("sid: %x" % (sid.get()))
|
||||
print("gonna poke: %x %x" % (0x1000+4*new_ep, ip_addr))
|
||||
uio_obj.poke32(0x1800 + 4*new_ep, mac_addr & 0xFFFFFFFF)
|
||||
print("gonna poke: %x %x" % (0x1800+4*new_ep, mac_addr))
|
||||
port = int(port)
|
||||
uio_obj.poke32(0x1400 + 4*new_ep, ((int(port) << 16) | (mac_addr >> 32)))
|
||||
print("gonna poke: %x %x" % (0x1400+4*new_ep, ((port << 16) | (mac_addr >> 32))))
|
||||
return sid.get()
|
||||
|
||||
@ -16,19 +16,22 @@
|
||||
#
|
||||
|
||||
import pyudev
|
||||
import os
|
||||
from logging import getLogger
|
||||
LOG = getLogger(__name__)
|
||||
|
||||
|
||||
def get_eeprom(address):
|
||||
def get_eeprom_path(address):
|
||||
"""
|
||||
Return EEPROM device path for a given I2C address
|
||||
"""
|
||||
context = pyudev.Context()
|
||||
parent = pyudev.Device.from_name(context, "platform", address)
|
||||
paths = [device.dev_node if device.dev_node is not None else device.sys_path
|
||||
paths = [device.device_node if device.device_node is not None else device.sys_path
|
||||
for device in context.list_devices(parent=parent, subsystem="nvmem")]
|
||||
if len(paths) != 1:
|
||||
raise Exception("{0} paths to EEPROM found!".format(len(paths)))
|
||||
return paths[0]
|
||||
return paths[0] + "/nvmem"
|
||||
|
||||
|
||||
def get_spidev_nodes(spi_master):
|
||||
@ -37,6 +40,30 @@ def get_spidev_nodes(spi_master):
|
||||
"""
|
||||
context = pyudev.Context()
|
||||
parent = pyudev.Device.from_name(context, "platform", spi_master)
|
||||
paths = [device.dev_node if device.dev_node is not None else device.sys_path
|
||||
paths = [device.sys_path
|
||||
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.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)
|
||||
|
||||
@ -185,20 +185,18 @@ class MPMServer(RPCServer):
|
||||
This is as safe method which can be called without a claim on the device
|
||||
"""
|
||||
info = self.periph_manager._get_device_info()
|
||||
if self.host in ["127.0.0.1", "::1"]:
|
||||
if self.client_host in ["127.0.0.1", "::1"]:
|
||||
info["connection"] = "local"
|
||||
else:
|
||||
info["connection"] = "remote"
|
||||
return info
|
||||
|
||||
def probe_interface(self, token):
|
||||
def allocate_sid(self, token, *args):
|
||||
"""
|
||||
Forwards the call to periph_manager._probe_interface with the client ip addresss
|
||||
as argument. Should be used to probe the data interfaces on the device
|
||||
Forwards the call to periph_manager._allocate_sid with the client ip addresss
|
||||
as argument. Should be used to setup interfaces
|
||||
"""
|
||||
if token[:256] != self._state.claim_token.value:
|
||||
return False
|
||||
return self.periph_manager._probe_interface(self.host)
|
||||
return self.periph_manager._allocate_sid(self.client_host, *args)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -45,35 +45,58 @@ class SharedState(object):
|
||||
lock=self.lock) # String with max length of 256
|
||||
|
||||
|
||||
class SID(object):
|
||||
def __init__(self, sid=0):
|
||||
self.src_addr = sid >> 24
|
||||
self.src_ep = (sid >> 16) & 0xFF
|
||||
self.dst_addr = (sid >> 8) & 0xFF
|
||||
self.dst_ep = sid & 0xFF
|
||||
|
||||
def set_src_addr(self, new_addr):
|
||||
self.src_addr = new_addr & 0xFF
|
||||
|
||||
def set_dst_addr(self, new_addr):
|
||||
self.dst_addr = new_addr & 0xFF
|
||||
|
||||
def set_src_ep(self, new_addr):
|
||||
self.src_ep = new_addr & 0xFF
|
||||
|
||||
def set_dst_ep(self, new_addr):
|
||||
self.dst_ep = new_addr & 0xFF
|
||||
|
||||
def get(self):
|
||||
return (self.src_addr << 24) | (self.src_ep << 16) | (self.dst_addr << 8) | self.dst_ep
|
||||
|
||||
|
||||
class EEPROM(object):
|
||||
"""
|
||||
Reads out common properties and rawdata out of a nvmem path
|
||||
"""
|
||||
# eeprom_header contains:
|
||||
# 4 bytes magic
|
||||
# 4 bytes CRC
|
||||
# 2 bytes data_version
|
||||
# 4 bytes version
|
||||
# 4x4 bytes mcu_flags -> throw them away
|
||||
# 2 bytes hw_pid
|
||||
# 2 bytes hw_rev
|
||||
# 2 bytes pad
|
||||
#
|
||||
# 16 bytes in total
|
||||
eeprom_header = struct.Struct("I I H H H 2x")
|
||||
# 28 bytes in total
|
||||
eeprom_header = struct.Struct("!I I 16x H H")
|
||||
|
||||
def read_eeprom(self, nvmem_path):
|
||||
"""
|
||||
Read the EEPROM located at nvmem_path and return a tuple (header, body)
|
||||
Read the EEPROM located at nvmem_path and return a tuple (header, data)
|
||||
Header is already parsed in the common header fields
|
||||
Data contains the full eeprom data structure
|
||||
"""
|
||||
with open(nvmem_path, "rb") as nvmem_file:
|
||||
header = nvmem_file.read(16)
|
||||
data = nvmem_file.read(240)
|
||||
header = self.eeprom_header.unpack(header)
|
||||
data = nvmem_file.read(256)
|
||||
_header = self.eeprom_header.unpack_from(data)
|
||||
print hex(_header[0]), hex(_header[1]), hex(_header[2]), hex(_header[3])
|
||||
header = {
|
||||
"magic": header[0],
|
||||
"crc": header[1],
|
||||
"data_version": header[2],
|
||||
"hw_pid": header[3],
|
||||
"hw_rev": header[4],
|
||||
"magic": _header[0],
|
||||
"version": _header[1],
|
||||
"hw_pid": _header[2],
|
||||
"hw_rev": _header[3],
|
||||
}
|
||||
print header
|
||||
return (header, data)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user