From 35afd59956ee330df1201e7dbf344000a109b114 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 30 Aug 2022 18:53:35 +0200 Subject: [PATCH] tools/litex_server/litex_client: Add initial information exchange and improve PCIe case. Due to the address translation done with the LitePCIe bridge (remapping CSR to 0), RemoteClient needs to know which bridge is used to also translate CSRs. This commit adds an initial information exchange between server and client and avoid the PCIe workarounds. --- litex/tools/litex_client.py | 16 ++++++++-------- litex/tools/litex_server.py | 25 +++++++++++++++++++------ litex/tools/litex_term.py | 4 ---- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/litex/tools/litex_client.py b/litex/tools/litex_client.py index 3abb57628..e59b77154 100644 --- a/litex/tools/litex_client.py +++ b/litex/tools/litex_client.py @@ -36,11 +36,19 @@ class RemoteClient(EtherboneIPC, CSRBuilder): self.debug = debug self.base_address = base_address if base_address is not None else 0 + def _receive_server_info(self): + info = str(self.socket.recv(128)) + + # With LitePCIe, CSRs are translated to 0 to limit BAR0 size, so also translate base address. + if "CommPCIe" in info: + self.base_address = -self.mems.csr.base + def open(self): if hasattr(self, "socket"): return self.socket = socket.create_connection((self.host, self.port), 5.0) self.socket.settimeout(5.0) + self._receive_server_info() def close(self): if not hasattr(self, "socket"): @@ -99,10 +107,6 @@ def dump_identifier(host, csr_csv, port): bus = RemoteClient(host=host, csr_csv=csr_csv, port=port) bus.open() - # On PCIe designs, CSR is remapped to 0 to limit BAR0 size. - if hasattr(bus.bases, "pcie_phy"): - bus.base_address = -bus.mems.csr.base - fpga_identifier = "" for i in range(256): @@ -119,10 +123,6 @@ def dump_registers(host, csr_csv, port, filter=None): bus = RemoteClient(host=host, csr_csv=csr_csv, port=port) bus.open() - # On PCIe designs, CSR is remapped to 0 to limit BAR0 size. - if hasattr(bus.bases, "pcie_phy"): - bus.base_address = -bus.mems.csr.base - for name, register in bus.regs.__dict__.items(): if (filter is None) or filter in name: print("0x{:08x} : 0x{:08x} {}".format(register.addr, register.read(), name)) diff --git a/litex/tools/litex_server.py b/litex/tools/litex_server.py index af2442a19..8a8f6339a 100755 --- a/litex/tools/litex_server.py +++ b/litex/tools/litex_server.py @@ -96,35 +96,48 @@ class RemoteServer(EtherboneIPC): self.socket.close() del self.socket + def _send_server_info(self, client_socket): + # FIXME: Formalize info/improve. + info = [] + info.append(f"{self.comm.__class__.__name__}") + info.append(f"{self.bind_ip}") + info.append(f"{self.bind_port}") + info = ":".join(info) + client_socket.sendall(bytes(info, "UTF-8")) + def _serve_thread(self): while True: client_socket, addr = self.socket.accept() + self._send_server_info(client_socket) print("Connected with " + addr[0] + ":" + str(addr[1])) try: + # Serve Etherbone reads/writes. while True: + # Receive packet. try: packet = self.receive_packet(client_socket) if packet == 0: break except: break + + # Decode Packet. packet = EtherbonePacket(packet) packet.decode() + # Get Packet's Record. record = packet.records.pop() - # Wait for lock + # Hardware lock/reservation. while self.lock: time.sleep(0.01) - - # Set lock self.lock = True - # Handle writes: + # Handle Etherbone writes. if record.writes != None: self.comm.write(record.writes.base_addr, record.writes.get_datas()) - # Handle reads + # Handle Etherbone reads. if record.reads != None: max_length = { "CommUART": 256, @@ -148,7 +161,7 @@ class RemoteServer(EtherboneIPC): packet.encode() self.send_packet(client_socket, packet) - # release lock + # Release hardware lock. self.lock = False finally: diff --git a/litex/tools/litex_term.py b/litex/tools/litex_term.py index bf72d390e..a0e76ad9e 100755 --- a/litex/tools/litex_term.py +++ b/litex/tools/litex_term.py @@ -97,10 +97,6 @@ class CrossoverUART: if not present: raise ValueError(f"CrossoverUART {name} not present in design.") - # FIXME: On PCIe designs, CSR is remapped to 0 to limit BAR0 size. - if base_address is None and hasattr(self.bus.bases, "pcie_phy"): - self.bus.base_address = -self.bus.mems.csr.base - def open(self): self.bus.open() self.file, self.name = pty.openpty()