mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-11-10 02:53:53 +01:00
Build and Deploy on local RHEL9 / build (push) Successful in 2m0s
Build on RHEL9 docker image / build (push) Successful in 5m0s
Build and Deploy on local RHEL8 / build (push) Successful in 5m10s
Build on RHEL8 docker image / build (push) Successful in 5m27s
Run Simulator Tests on local RHEL9 / build (push) Successful in 20m41s
Run Simulator Tests on local RHEL8 / build (push) Successful in 24m6s
* replaced bf specific usleep replacement with one using cycle counts to be stable while changing optimization levels * uint32_t signature on usleep since the register read is 32bit... * enabled -O2 for ctb and mythen + a few additional warnings * configure stack size for blackfin servers to 256kB instead of the default 4kB * enable opt for JF and Moench, ratemax make local for eiger * fixed misplaced volatile on Beb_Read32 * removed dead code in eiger server (which had 2 byte read passt end), usleep_bf returns -1 for sleeps that can't be represented * deal with fall through of table filling in ratecorr table * memory clobber for inline asm and added flags on eiger * -O2 for gotthard and xilinx * fixes to remove the new warnings * fixed new eiger warnings * binaries in --------- Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
223 lines
6.9 KiB
C
223 lines
6.9 KiB
C
// SPDX-License-Identifier: LGPL-3.0-or-other
|
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
#include "LocalLinkInterface.h"
|
|
#include "HardwareMMappingDefs.h"
|
|
#include "clogger.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
|
|
void Local_LocalLinkInterface(struct LocalLinkInterface *ll,
|
|
unsigned int ll_fifo_badr) {
|
|
LOG(logDEBUG1, ("Initialize PLB LL FIFOs\n"));
|
|
ll->ll_fifo_base = 0;
|
|
ll->ll_fifo_ctrl_reg = 0;
|
|
if (Local_Init(ll, ll_fifo_badr)) {
|
|
Local_Reset(ll);
|
|
LOG(logDEBUG1,
|
|
("\tFIFO Status : 0x%08x\n\n\n", Local_StatusVector(ll)));
|
|
} else
|
|
LOG(logERROR,
|
|
("\tCould not map LocalLink : 0x%08x\n\n\n", ll_fifo_badr));
|
|
}
|
|
|
|
int Local_Init(struct LocalLinkInterface *ll, unsigned int ll_fifo_badr) {
|
|
int fd;
|
|
void *plb_ll_fifo_ptr;
|
|
|
|
if ((fd = open("/dev/mem", O_RDWR)) < 0) {
|
|
LOG(logERROR, ("Could not open /dev/mem for local link\n"));
|
|
return 0;
|
|
}
|
|
|
|
plb_ll_fifo_ptr = mmap(0, getpagesize(), PROT_READ | PROT_WRITE,
|
|
MAP_FILE | MAP_SHARED, fd, ll_fifo_badr);
|
|
close(fd);
|
|
|
|
if (plb_ll_fifo_ptr == MAP_FAILED) {
|
|
LOG(logERROR, ("mmap error for local link\n"));
|
|
return 0;
|
|
}
|
|
|
|
ll->ll_fifo_base = (xfs_u32)plb_ll_fifo_ptr;
|
|
ll->ll_fifo_ctrl_reg = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int Local_Reset(struct LocalLinkInterface *ll) {
|
|
return Local_Reset1(ll, PLB_LL_FIFO_CTRL_RESET_STD);
|
|
}
|
|
|
|
int Local_Reset1(struct LocalLinkInterface *ll, unsigned int rst_mask) {
|
|
ll->ll_fifo_ctrl_reg |= rst_mask;
|
|
LOG(logDEBUG1, ("\tCTRL Register bits: 0x%08x\n", ll->ll_fifo_ctrl_reg));
|
|
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
|
|
ll->ll_fifo_ctrl_reg &= (~rst_mask);
|
|
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
return 1;
|
|
}
|
|
|
|
unsigned int Local_StatusVector(struct LocalLinkInterface *ll) {
|
|
return HWIO_xfs_in32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_STATUS);
|
|
}
|
|
|
|
int Local_Write(struct LocalLinkInterface *ll, unsigned int buffer_len,
|
|
void *buffer) {
|
|
|
|
// note: buffer must be word (4 byte) aligned
|
|
// frame_len in byte
|
|
int vacancy = 0;
|
|
int words_send = 0;
|
|
int last_word;
|
|
unsigned int *word_ptr;
|
|
unsigned int fifo_ctrl;
|
|
xfs_u32 status;
|
|
|
|
if (buffer_len < 1) {
|
|
return -1;
|
|
}
|
|
|
|
last_word = (buffer_len - 1) / 4;
|
|
word_ptr = (unsigned int *)buffer;
|
|
|
|
LOG(logDEBUG1, ("LL Write - Len: %2d - If: %X - Data: ", buffer_len,
|
|
ll->ll_fifo_base));
|
|
for (int i = 0; i < (int)buffer_len / 4; i++)
|
|
LOG(logDEBUG1, ("%.8X ", *(((unsigned *)buffer) + i)));
|
|
|
|
while (words_send <= last_word) {
|
|
while (!vacancy) // wait for Fifo to be empty again
|
|
{
|
|
status =
|
|
HWIO_xfs_in32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_STATUS);
|
|
if ((status & PLB_LL_FIFO_STATUS_ALMOSTFULL) == 0)
|
|
vacancy = 1;
|
|
if (vacancy == 0) {
|
|
LOG(logERROR, ("Fifo full!\n"));
|
|
}
|
|
}
|
|
|
|
// Just to know: #define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100
|
|
for (int i = 0; ((i < PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS) &&
|
|
(words_send <= last_word));
|
|
i++) {
|
|
fifo_ctrl = 0;
|
|
if (words_send == 0) {
|
|
fifo_ctrl =
|
|
PLB_LL_FIFO_CTRL_LL_SOF; // announce the start of file
|
|
}
|
|
|
|
if (words_send == last_word) {
|
|
fifo_ctrl |=
|
|
(PLB_LL_FIFO_CTRL_LL_EOF |
|
|
(((buffer_len - 1) << PLB_LL_FIFO_CTRL_LL_REM_SHIFT) &
|
|
PLB_LL_FIFO_CTRL_LL_REM));
|
|
}
|
|
Local_ctrl_reg_write_mask(ll, PLB_LL_FIFO_CTRL_LL_MASK, fifo_ctrl);
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_FIFO,
|
|
word_ptr[words_send++]);
|
|
}
|
|
}
|
|
|
|
return buffer_len;
|
|
}
|
|
|
|
int Local_Read(struct LocalLinkInterface *ll, unsigned int buffer_len,
|
|
void *buffer) {
|
|
|
|
static unsigned int buffer_ptr = 0;
|
|
// note: buffer must be word (4 byte) aligned
|
|
// frame_len in byte
|
|
int len;
|
|
unsigned int *word_ptr;
|
|
unsigned int status;
|
|
volatile unsigned int fifo_val;
|
|
int sof = 0;
|
|
|
|
LOG(logDEBUG1, ("LL Read - If: %X - Data: ", ll->ll_fifo_base));
|
|
|
|
word_ptr = (unsigned int *)buffer;
|
|
do {
|
|
status = HWIO_xfs_in32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_STATUS);
|
|
|
|
if (!(status & PLB_LL_FIFO_STATUS_EMPTY)) {
|
|
if (status & PLB_LL_FIFO_STATUS_LL_SOF) {
|
|
if (buffer_ptr) {
|
|
buffer_ptr = 0;
|
|
return -1; // buffer overflow
|
|
}
|
|
buffer_ptr = 0;
|
|
sof = 1;
|
|
}
|
|
|
|
fifo_val = HWIO_xfs_in32(
|
|
ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_FIFO); // read from fifo
|
|
|
|
if ((buffer_ptr > 0) || sof) {
|
|
if ((buffer_len >> 2) > buffer_ptr) {
|
|
LOG(logDEBUG1, ("%.8X ", fifo_val));
|
|
word_ptr[buffer_ptr++] = fifo_val; // write to buffer
|
|
} else {
|
|
buffer_ptr = 0;
|
|
return -2; // buffer overflow
|
|
}
|
|
|
|
if (status & PLB_LL_FIFO_STATUS_LL_EOF) {
|
|
len = (buffer_ptr << 2) - 3 +
|
|
((status & PLB_LL_FIFO_STATUS_LL_REM) >>
|
|
PLB_LL_FIFO_STATUS_LL_REM_SHIFT);
|
|
LOG(logDEBUG1, ("Len: %d\n", len));
|
|
buffer_ptr = 0;
|
|
return len;
|
|
}
|
|
}
|
|
}
|
|
} while (!(status & PLB_LL_FIFO_STATUS_EMPTY));
|
|
return 0;
|
|
}
|
|
|
|
int Local_ctrl_reg_write_mask(struct LocalLinkInterface *ll, unsigned int mask,
|
|
unsigned int val) {
|
|
ll->ll_fifo_ctrl_reg &= (~mask);
|
|
ll->ll_fifo_ctrl_reg |= (mask & val);
|
|
HWIO_xfs_out32(ll->ll_fifo_base + 4 * PLB_LL_FIFO_REG_CTRL,
|
|
ll->ll_fifo_ctrl_reg);
|
|
return 1;
|
|
}
|
|
|
|
int Local_Test(struct LocalLinkInterface *ll, unsigned int buffer_len,
|
|
void *buffer) {
|
|
|
|
int len;
|
|
unsigned int rec_buff_len = 4096;
|
|
unsigned int rec_buffer[4097];
|
|
|
|
Local_Write(ll, buffer_len, buffer);
|
|
usleep(10000);
|
|
|
|
do {
|
|
len = Local_Read(ll, rec_buff_len, rec_buffer);
|
|
LOG(logDEBUG1, ("receive length: %i\n", len));
|
|
|
|
if (len > 0) {
|
|
rec_buffer[len] = 0;
|
|
LOG(logINFO, ("%s\n", (char *)rec_buffer));
|
|
}
|
|
} while (len > 0);
|
|
|
|
return 1;
|
|
}
|