From 7904a03e4b3370f77e7e1746a1a2d2971d837064 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Wed, 6 Sep 2023 09:19:39 +0200 Subject: [PATCH] PCIe driver: add functions to load/save internal packet generator memory --- fpga/pcie_driver/jfjoch_drv.h | 17 ++++++---- fpga/pcie_driver/jfjoch_function.c | 8 +++++ fpga/pcie_driver/jfjoch_ioctl.c | 23 +++++++++++++ fpga/pcie_driver/jfjoch_ioctl.h | 2 ++ receiver/CMakeLists.txt | 4 +++ receiver/PCIExpressDevice.cpp | 6 ++++ receiver/PCIExpressDevice.h | 1 + receiver/jfjoch_pcie_read_int_packet_gen.cpp | 35 ++++++++++++++++++++ 8 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 receiver/jfjoch_pcie_read_int_packet_gen.cpp diff --git a/fpga/pcie_driver/jfjoch_drv.h b/fpga/pcie_driver/jfjoch_drv.h index ee6c443c..181e5717 100644 --- a/fpga/pcie_driver/jfjoch_drv.h +++ b/fpga/pcie_driver/jfjoch_drv.h @@ -35,12 +35,13 @@ // Offset for BAR #0 for action configuration -#define ACTION_CONFIG_OFFSET (0x10000) -#define MAILBOX_OFFSET (0x30000) -#define CALIB_BRAM_OFFSET (0x60000) -#define CMS_OFFSET (0xC0000) -#define CMAC_OFFSET (0x20000) -#define PCIE_OFFSET (0x90000) +#define ACTION_CONFIG_OFFSET (0x010000) +#define MAILBOX_OFFSET (0x030000) +#define CALIB_BRAM_OFFSET (0x060000) +#define CMS_OFFSET (0x0C0000) +#define CMAC_OFFSET (0x020000) +#define PCIE_OFFSET (0x090000) +#define INT_PKT_GEN_OFFSET (0x100000) #define ADDR_CMS_CONTROL_REG 0x028018 #define ADDR_CMS_MB_RESETN_REG 0x020000 @@ -52,6 +53,8 @@ #define ADDR_CMS_HBM_TEMP1_INS_REG 0x028268 // in C #define ADDR_CMS_HBM_TEMP2_INS_REG 0x0282BC // in C +#define INT_PKT_GEN_FRAME_SIZE_BYTES (512U*1024U*2UL) + struct jfjoch_buf { dma_addr_t dma_address; void *kernel_address; @@ -100,6 +103,8 @@ void jfjoch_set_mac_addr(struct jfjoch_drvdata *drvdata, u64 *mac_addr); void jfjoch_get_mac_addr(struct jfjoch_drvdata *drvdata, u64 *mac_addr); void jfjoch_set_ipv4_addr(struct jfjoch_drvdata *drvdata, const u32 *addr); void jfjoch_get_ipv4_addr(struct jfjoch_drvdata *drvdata, u32 *addr); +void jfjoch_load_int_pkt_gen(struct jfjoch_drvdata *drvdata, char* output); +void jfjoch_save_int_pkt_gen(struct jfjoch_drvdata *drvdata, const char* input); u64 jfjoch_read_mac_addr(struct jfjoch_drvdata *drvdata); diff --git a/fpga/pcie_driver/jfjoch_function.c b/fpga/pcie_driver/jfjoch_function.c index 86475a8e..743afa96 100644 --- a/fpga/pcie_driver/jfjoch_function.c +++ b/fpga/pcie_driver/jfjoch_function.c @@ -85,6 +85,14 @@ int jfjoch_send_wr(struct jfjoch_drvdata *drvdata, u32 handle) { return 0; } +void jfjoch_load_int_pkt_gen(struct jfjoch_drvdata *drvdata, char* output) { + memcpy_fromio(output, drvdata->bar0 + INT_PKT_GEN_OFFSET, INT_PKT_GEN_FRAME_SIZE_BYTES); +} + +void jfjoch_save_int_pkt_gen(struct jfjoch_drvdata *drvdata, const char* input) { + memcpy_toio(drvdata->bar0 + INT_PKT_GEN_OFFSET, input, INT_PKT_GEN_FRAME_SIZE_BYTES); +} + int jfjoch_read_wc(struct jfjoch_drvdata *drvdata, u32 *output) { u32 rta; int i; diff --git a/fpga/pcie_driver/jfjoch_ioctl.c b/fpga/pcie_driver/jfjoch_ioctl.c index ac899287..bad7b9cc 100644 --- a/fpga/pcie_driver/jfjoch_ioctl.c +++ b/fpga/pcie_driver/jfjoch_ioctl.c @@ -11,6 +11,7 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ActionEnvParams env_params; u32 exchange[16]; int err; + void *tmp = NULL; switch (cmd) { case IOCTL_JFJOCH_START: @@ -96,6 +97,28 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { case IOCTL_JFJOCH_DEFAULT_MAC: jfjoch_read_mac_addr(drvdata); return 0; + case IOCTL_JFJOCH_SET_INT_PKT: + tmp = vmalloc(INT_PKT_GEN_FRAME_SIZE_BYTES); + if (tmp == NULL) + return -ENOMEM; + if (copy_from_user(tmp, (char *) arg, INT_PKT_GEN_FRAME_SIZE_BYTES) != 0) { + vfree(tmp); + return -EFAULT; + } + jfjoch_save_int_pkt_gen(drvdata, tmp); + vfree(tmp); + return 0; + case IOCTL_JFJOCH_GET_INT_PKT: + tmp = vmalloc(INT_PKT_GEN_FRAME_SIZE_BYTES); + if (tmp == NULL) + return -ENOMEM; + jfjoch_load_int_pkt_gen(drvdata, tmp); + if (copy_to_user((char *) arg, tmp, INT_PKT_GEN_FRAME_SIZE_BYTES) != 0) { + vfree(tmp); + return -EFAULT; + } + vfree(tmp); + return 0; default: return -ENOTTY; } diff --git a/fpga/pcie_driver/jfjoch_ioctl.h b/fpga/pcie_driver/jfjoch_ioctl.h index 1fcdef6a..c85f70ef 100644 --- a/fpga/pcie_driver/jfjoch_ioctl.h +++ b/fpga/pcie_driver/jfjoch_ioctl.h @@ -33,5 +33,7 @@ #define IOCTL_JFJOCH_DEFAULT_MAC _IO (IOCTL_JFJOCH_MAGIC, 16) #define IOCTL_JFJOCH_SET_IPV4 _IOW(IOCTL_JFJOCH_MAGIC, 17, uint32_t) #define IOCTL_JFJOCH_GET_IPV4 _IOR(IOCTL_JFJOCH_MAGIC, 18, uint32_t) +#define IOCTL_JFJOCH_SET_INT_PKT _IOW(IOCTL_JFJOCH_MAGIC, 19, char *) +#define IOCTL_JFJOCH_GET_INT_PKT _IOR(IOCTL_JFJOCH_MAGIC, 20, char *) #endif //JUNGFRAUJOCH_JFJOCH_IOCTL_H diff --git a/receiver/CMakeLists.txt b/receiver/CMakeLists.txt index 3f0f2feb..999b8d4a 100644 --- a/receiver/CMakeLists.txt +++ b/receiver/CMakeLists.txt @@ -45,6 +45,10 @@ ADD_EXECUTABLE(jfjoch_pcie_clear_net_counters jfjoch_pcie_clear_net_counters.cpp TARGET_LINK_LIBRARIES(jfjoch_pcie_clear_net_counters JungfraujochHost) INSTALL(TARGETS jfjoch_pcie_clear_net_counters RUNTIME) +ADD_EXECUTABLE(jfjoch_pcie_read_int_packet_gen jfjoch_pcie_read_int_packet_gen.cpp) +TARGET_LINK_LIBRARIES(jfjoch_pcie_read_int_packet_gen JungfraujochHost) +INSTALL(TARGETS jfjoch_pcie_read_int_packet_gen RUNTIME) + ADD_LIBRARY(JFJochReceiver STATIC JFJochReceiverService.cpp JFJochReceiverService.h JFJochReceiverTest.cpp JFJochReceiverTest.h diff --git a/receiver/PCIExpressDevice.cpp b/receiver/PCIExpressDevice.cpp index aa96416e..89516472 100644 --- a/receiver/PCIExpressDevice.cpp +++ b/receiver/PCIExpressDevice.cpp @@ -201,3 +201,9 @@ std::string PCIExpressDevice::GetIPv4Address() const { "Failed getting MAC address", errno); return IPv4AddressToStr(tmp); } + +void PCIExpressDevice::HW_ReadInternalPacketGen(uint16_t *tmp) const { + if (ioctl(fd, IOCTL_JFJOCH_GET_INT_PKT, tmp) != 0) + throw JFJochException(JFJochExceptionCategory::PCIeError, + "Failed getting internal packet generator frame", errno); +} diff --git a/receiver/PCIExpressDevice.h b/receiver/PCIExpressDevice.h index c87e40d1..84ba403a 100644 --- a/receiver/PCIExpressDevice.h +++ b/receiver/PCIExpressDevice.h @@ -30,6 +30,7 @@ public: void Cancel() override; void HW_GetStatus(ActionStatus *status) const override; void HW_GetEnvParams(ActionEnvParams *status) const override; + void HW_ReadInternalPacketGen(uint16_t *tmp) const; uint32_t GetNumKernelBuffers() const; int32_t GetNUMANode() const override; diff --git a/receiver/jfjoch_pcie_read_int_packet_gen.cpp b/receiver/jfjoch_pcie_read_int_packet_gen.cpp new file mode 100644 index 00000000..c8130fe6 --- /dev/null +++ b/receiver/jfjoch_pcie_read_int_packet_gen.cpp @@ -0,0 +1,35 @@ +// Copyright (2019-2022) Paul Scherrer Institute +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +#include "../common/JFJochException.h" +#include "PCIExpressDevice.h" +#include "../common/Logger.h" +#include + +int main(int argc, char **argv) { + Logger logger("jfjoch_pcie_read_int_packet_gen"); + + if (argc != 2) { + logger.Error("Usage: ./jfjoch_pcie_read_int_packet_gen "); + exit(EXIT_FAILURE); + } + logger.Info("Device {}", argv[1]); + std::cout << std::endl; + try { + PCIExpressDevice test(argv[1], 0); + + std::vector data(RAW_MODULE_SIZE*2); + + test.HW_ReadInternalPacketGen((uint16_t *) data.data()); + + std::ofstream file("out.bin", std::ios::binary); + file.write((char *) data.data(), data.size()); + file.close(); + + logger.Info("Done"); + } catch (const JFJochException &e) { + logger.ErrorException(e); + } +} \ No newline at end of file