Commit 1ae74421 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

include: commented MQ headers, removed fixed constants

parent 40b79b0e
......@@ -10,39 +10,122 @@
/*.
* White Rabbit Node Core
*
* mqueue.h: MQ register definitions
* mqueue.h: MQ register definitions (Host side)
*/
#ifndef __MQUEUE_H
#define __MQUEUE_H
// Nax number of supported incoming/outgoing slots
#define MAX_MQUEUE_SLOTS 16
// HMQ base address (wrs to the base addr of the WR Node Core)
#define BASE_HMQ 0x00000
// Global Control Regs
#define MQUEUE_GCR (0x0)
// Incoming slot base address
#define MQUEUE_IN(slot) (0x4000 + (slot) * 0x400)
// Outgoung slot base address
#define MQUEUE_OUT(slot) (0x8000 + (slot) * 0x400)
// Global Control Registers base address, relative to BASE_HMQ (SLOT_COUNT, SLOT_STATUS, interrupt control, etc).
// Common for all incoming/outgoing slots in the queue
#define MQUEUE_BASE_GCR (0x0)
// Incoming slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_IN(slot) (0x4000 + (slot) * 0x400)
// Outgoung slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_OUT(slot) (0x8000 + (slot) * 0x400)
// MQ slot registers, relative to the base address of each slot: MQUEUE_BASE_IN(slot_no) or MQUEUE_BASE_OUT(slot_no)
#define MQUEUE_SLOT_COMMAND 0
// Status register
#define MQUEUE_SLOT_STATUS 4
// Start of data block
#define MQUEUE_SLOT_DATA_START 8
// Layout of MQUEUE_SLOT_COMMAND register:
// MQ commands
// Claim: prepares a slot to send a message (w/o)
#define MQUEUE_CMD_CLAIM (1<<24)
// Purge: erases all messages from a slot (w/o)
#define MQUEUE_CMD_PURGE (1<<25)
// Ready: pushes the message to the queue. (w/o)
#define MQUEUE_CMD_READY (1<<26)
// Discard: removes last message from the queue, advancing to the next one (w/o)
#define MQUEUE_CMD_DISCARD (1<<27)
// MQ slot register offsets
#define MQUEUE_SLOT_COMMAND 0
#define MQUEUE_SLOT_STATUS 4
#define MQUEUE_SLOT_DATA_START 8
// Size of the message to be sent, in words (w/o). Must be written together with the
// READY command, e.g.:
// writel (MQUEUE_CMD_READY | 10, MQUEUE_SLOT_COMMAND);
#define MQUEUE_CMD_MSG_SIZE_MASK 0xff
#define MQUEUE_CMD_MSG_SIZE_SHIFT 0
// Layout of MQUEUE_SLOT_STATUS register:
// [0] Slot is full
#define MQUEUE_SLOT_STATUS_FULL (1<<0)
// [1] Slot is empty
#define MQUEUE_SLOT_STATUS_EMPTY (1<<1)
// MQ GCR register offsets
// [15:8] Number of occupied entries
#define MQUEUE_SLOT_STATUS_OCCUPIED_SHIFT 8
#define MQUEUE_SLOT_STATUS_OCCUPIED_MASK 0xff00
// [23:16] Number of transferred words in the message currently on top of the slot
#define MQUEUE_SLOT_STATUS_MSG_SIZE_SHIFT 16
#define MQUEUE_SLOT_STATUS_MSG_SIZE_MASK 0xff0000
// [31:28] log2(number of words in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_SHIFT 28
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_MASK 0xf0000000
// [7:2] log2(number of entries in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_SHIFT 2
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_MASK 0xfc
//
// MQ Global Control Registers.Adresses relative to MQUEUE_BASE_GCR:
//
#define MQUEUE_GCR_INCOMING_STATUS_MASK (0x0000ffff)
// Number of slots in this implementation of HMQ
#define MQUEUE_GCR_SLOT_COUNT 0
// EMPTY bits of all slots in a single register (for polling/IRQ status)
#define MQUEUE_GCR_SLOT_STATUS 4
// Interrupt mask (Outgoing: EMPTY, Incoming: not EMPTY)
#define MQUEUE_GCR_IRQ_MASK 8
// IRQ Coalescing register (reserved for future use)
#define MQUEUE_GCR_IRQ_COALESCE 12
#define MQUEUE_SLOT_STATUS_FULL (1<<0)
// Layout of SLOT_COUNT register
// [7:0] Number of Incoming slots
#define MQUEUE_GCR_SLOT_COUNT_N_IN_SHIFT 0
#define MQUEUE_GCR_SLOT_COUNT_N_IN_MASK 0xff
// [15:8] Number of Outgoing slots
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT 8
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK 0xff00
// Layout of SLOT_STATUS register
// [15:0] Outgoing slots status. Each bit indicates a NOT EMPTY status of the corresponding outgoing slot
#define MQUEUE_GCR_SLOT_STATUS_OUT_SHIFT 0
#define MQUEUE_GCR_SLOT_STATUS_OUT_MASK 0xffff
// [31:16] Incoming slots status. Each bit indicates an EMPTY status of the corresponding incoming slot
#define MQUEUE_GCR_SLOT_STATUS_IN_SHIFT 16
#define MQUEUE_GCR_SLOT_STATUS_IN_MASK 0xffff0000
// Layout of IRQ_MASK register
// [15:0] Outgoing slots status interrupt mask. Each bit enables generation of interrupt on NOT EMPTY status of the corresponding outgoing slot.
#define MQUEUE_GCR_IRQ_MASK_OUT_SHIFT 0
#define MQUEUE_GCR_IRQ_MASK_OUT_MASK 0xffff
// [31:16] Incoming slots status interrupt mask. Each bit enables generation of interrupt on EMPTY status of the corresponding incoming slot.
#define MQUEUE_GCR_IRQ_MASK_IN_SHIFT 16
#define MQUEUE_GCR_IRQ_MASK_IN_MASK 0xffff0000
// Layout of IRQ_COALSESCE register
// The register is left for future IRQ coalescing support (if ever needed)
#endif
......@@ -347,7 +347,7 @@ int list_out_trig_remove ( struct list_node *dev, struct list_trigger_handle *ha
req[1] = handle->ptr_cond;
req[2] = handle->ptr_trig;
printf("remove: %x %x %x\n", handle->channel, handle->ptr_cond, handle->ptr_trig);
// printf("remove: %x %x %x\n", handle->channel, handle->ptr_cond, handle->ptr_trig);
int n = rt_request(dev, 1, ID_FD_CMD_CHAN_REMOVE_TRIGGER, req, 3, rsp);
......@@ -387,7 +387,7 @@ int list_out_trig_get_all (struct list_node *dev, int output, struct list_output
uint32_t state = rsp[8];
printf("%d %d %x\n", bucket, index, state);
// printf("%d %d %x\n", bucket, index, state);
if (state != HASH_ENT_EMPTY && !(state & HASH_ENT_CONDITIONAL))
{
struct list_output_trigger_state *current = &triggers[count];
......@@ -402,6 +402,8 @@ int list_out_trig_get_all (struct list_node *dev, int output, struct list_output
current->delay_trig.cycles = rsp[6];
current->delay_trig.frac = rsp[7];
current->is_conditional = 0;
current->worst_latency_us = (rsp[17] + 124) / 125;
if(rsp[9]) // condition assigned?
{
current->is_conditional = 1;
......@@ -442,18 +444,23 @@ int list_out_get_state ( struct list_node *dev, int output, struct list_output_s
int n = rt_request(dev, 1, ID_FD_CMD_CHAN_GET_STATE, req, 1, rsp);
if(n == 28 && rsp[0] == ID_REP_STATE)
if(n == 29 && rsp[0] == ID_REP_STATE)
{
state->output = output;
state->executed_pulses = rsp[3];
state->missed_pulses_late = rsp[4];
state->missed_pulses_deadtime = rsp[5];
state->missed_pulses_overflow = rsp[6];
state->total_rx_packets = rsp[27];
state->rx_packets = rsp[27];
state->rx_loopback = rsp[28];
unbag_ts(rsp, 10, &state->last_executed.ts);
unbag_ts(rsp, 13, &state->last_enqueued.ts);
unbag_ts(rsp, 16, &state->last_programmed.ts);
printf("Correct\n");
return 0;
}
......@@ -470,5 +477,5 @@ int list_out_get_state ( struct list_node *dev, int output, struct list_output_s
obuf[24] = st->dead_time;
obuf[25] = st->width_cycles;
obuf[26] = st->worst_latency;*/
return -1;
}
......@@ -40,6 +40,7 @@ struct list_output_trigger_state {
struct list_timestamp delay_trig;
struct list_timestamp delay_cond;
struct list_trigger_handle handle;
int worst_latency_us;
};
struct list_output_state {
......@@ -60,7 +61,8 @@ struct list_output_state {
uint32_t dead_time;
uint32_t pulse_width;
struct list_timestamp worst_rx_delay;
uint32_t total_rx_packets;
uint32_t rx_packets;
uint32_t rx_loopback;
};
struct list_node;
......
......@@ -19,7 +19,6 @@
#define MAX_MQUEUE_SLOTS 16
#define BASE_HMQ 0x00000
#define BASE_CPU_CSR 0x10000
static int fd_base = 1;
......@@ -53,10 +52,6 @@ static void wrn_writel(struct wrn_dev *dev, uint32_t data, uint32_t addr)
return dev->fmc->writel(dev->fmc, data, dev->base + addr);
}
#define HMQ_OUT(x) (0x8000 + 0x400 *(x))
#define HMQ_IN(x) (0x4000 + 0x400 *(x))
#define HMQ_GCR 0
static uint32_t hmq_readl(struct wrn_dev *dev, uint32_t what, uint32_t offset)
{
return wrn_readl(dev, BASE_HMQ + what + offset);
......@@ -72,10 +67,10 @@ static int init_hmq( struct wrn_dev *dev )
uint32_t slot_count, slot_status;
int i, entries, width;
slot_count = hmq_readl (dev, HMQ_GCR, MQUEUE_GCR_SLOT_COUNT);
slot_count = hmq_readl (dev, MQUEUE_BASE_GCR, MQUEUE_GCR_SLOT_COUNT);
int n_in = slot_count & 0xff;
int n_out = (slot_count >> 8) & 0xff;
int n_in = (slot_count & MQUEUE_GCR_SLOT_COUNT_N_IN_MASK) >> MQUEUE_GCR_SLOT_COUNT_N_IN_SHIFT;
int n_out = (slot_count & MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK) >> MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT;
dev->hmq.n_in = n_in;
dev->hmq.n_out = n_out;
......@@ -84,18 +79,18 @@ static int init_hmq( struct wrn_dev *dev )
for(i=0 ; i<n_out; i++)
{
slot_status = hmq_readl (dev, HMQ_OUT(i), MQUEUE_SLOT_STATUS);
width = 1 << (( slot_status >> 28) & 0xf);
entries = 1 << (( slot_status >> 2) & 0x3f);
hmq_writel(dev, HMQ_OUT(i), MQUEUE_CMD_PURGE, MQUEUE_SLOT_COMMAND);
slot_status = hmq_readl (dev, MQUEUE_BASE_OUT(i), MQUEUE_SLOT_STATUS);
width = 1 << ((slot_status & MQUEUE_SLOT_STATUS_LOG2_WIDTH_MASK) >> MQUEUE_SLOT_STATUS_LOG2_WIDTH_SHIFT);
entries = 1 << ((slot_status & MQUEUE_SLOT_STATUS_LOG2_ENTRIES_MASK) >> MQUEUE_SLOT_STATUS_LOG2_ENTRIES_SHIFT);
hmq_writel(dev, MQUEUE_BASE_OUT(i), MQUEUE_CMD_PURGE, MQUEUE_SLOT_COMMAND);
DBG(" - out%d: width=%d, entries=%d\n", i, width, entries);
}
for(i =0 ; i<n_in; i++)
{
slot_status =hmq_readl(dev, HMQ_IN(i), MQUEUE_SLOT_STATUS);
width = 1 << (( slot_status >> 28) & 0xf);
entries = 1 << (( slot_status >> 2) & 0x3f);
hmq_writel(dev, HMQ_IN(i), MQUEUE_CMD_PURGE, MQUEUE_SLOT_COMMAND);
slot_status =hmq_readl(dev, MQUEUE_BASE_IN(i), MQUEUE_SLOT_STATUS);
width = 1 << ((slot_status & MQUEUE_SLOT_STATUS_LOG2_WIDTH_MASK) >> MQUEUE_SLOT_STATUS_LOG2_WIDTH_SHIFT);
entries = 1 << ((slot_status & MQUEUE_SLOT_STATUS_LOG2_ENTRIES_MASK) >> MQUEUE_SLOT_STATUS_LOG2_ENTRIES_SHIFT);
hmq_writel(dev, MQUEUE_BASE_IN(i), MQUEUE_CMD_PURGE, MQUEUE_SLOT_COMMAND);
DBG(" - in%d: width=%d, entries=%d\n", i, width, entries);
}
return 0;
......@@ -156,20 +151,14 @@ int wrn_cpu_count( struct wrn_dev* dev)
int wrn_cpu_stop ( struct wrn_dev* dev, uint32_t mask )
{
uint32_t r = wrn_readl(dev, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
//DBG("cpu_stop: r %x mask %x csrbase %x\n", r, mask, BASE_CPU_CSR +WRN_CPU_CSR_REG_RESET);
r |= mask;
//DBG("cpu_stop: r %x \n", r);
wrn_writel(dev, r, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
wrn_writel(dev, r | mask, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
return 0;
}
int wrn_cpu_start ( struct wrn_dev * dev, uint32_t mask )
{
uint32_t r = wrn_readl(dev, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
//DBG("cpu_stop: r %x mask %x csrbase %x\n", r, mask, BASE_CPU_CSR +WRN_CPU_CSR_REG_RESET);
r &= ~mask;
//DBG("cpu_start: r %x \n", r);
wrn_writel(dev, r, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
wrn_writel(dev, r & ~mask, BASE_CPU_CSR + WRN_CPU_CSR_REG_RESET );
return 0;
}
......@@ -261,40 +250,31 @@ int wrn_cpu_load_file ( struct wrn_dev *dev, int cpu, const char *filename)
}
#define SLOT_OUT_MASK 0xffff
//#define SLOT_OUT_MASK 0xffff
static bool do_rx(struct wrn_dev *dev, wrn_message& msg, int& slot)
{
uint32_t in_stat = hmq_readl(dev, HMQ_GCR, MQUEUE_GCR_SLOT_STATUS);
//uint32_t cnt = hmq_readl(dev, HMQ_GCR, MQUEUE_GCR_SLOT_COUNT);
uint32_t in_stat = hmq_readl(dev, MQUEUE_BASE_GCR, MQUEUE_GCR_SLOT_STATUS);
/*DBG("gcr %x\n", in_stat);
if(in_stat & 1)
{
DBG("Got!\n");
}*/
if(in_stat & SLOT_OUT_MASK)
if(in_stat & MQUEUE_GCR_SLOT_STATUS_OUT_MASK)
{
int i, j;
for(i = 0; i < dev->hmq.n_out; i++)
{
if (in_stat & (1<<i))
{
uint32_t slot_stat = hmq_readl (dev, HMQ_OUT(i), MQUEUE_SLOT_STATUS );
int size = (slot_stat >> 16) & 0xff;
uint32_t slot_stat = hmq_readl (dev, MQUEUE_BASE_OUT(i), MQUEUE_SLOT_STATUS );
int size = (slot_stat & MQUEUE_SLOT_STATUS_MSG_SIZE_MASK) >> MQUEUE_SLOT_STATUS_MSG_SIZE_SHIFT;
msg.clear();
for(j=0;j<size;j++)
for(j=0;j<size;j++)
{
uint32_t rv = hmq_readl(dev, HMQ_OUT(i), MQUEUE_SLOT_DATA_START + j * 4);
uint32_t rv = hmq_readl(dev, MQUEUE_BASE_OUT(i), MQUEUE_SLOT_DATA_START + j * 4);
msg.push_back(rv);
//DBG("rv %x %x %c\n", MQUEUE_SLOT_DATA_START + j * 4, rv, (char) rv );
}
slot = i;
hmq_writel(dev, HMQ_OUT(i), MQUEUE_CMD_DISCARD, MQUEUE_SLOT_COMMAND);
slot = i;
hmq_writel(dev, MQUEUE_BASE_OUT(i), MQUEUE_CMD_DISCARD, MQUEUE_SLOT_COMMAND);
if (msg[0] == 0xdeadbeef)
{
......@@ -313,27 +293,22 @@ static bool do_rx(struct wrn_dev *dev, wrn_message& msg, int& slot)
return false;
}
//struct wrn_dev* wrn_open_by_fmc ( int device_id );
//struct wrn_dev* wrn_open( const char *device );
bool tx_ready(struct wrn_dev *dev, int slot)
{
uint32_t slot_stat = hmq_readl (dev, HMQ_IN(slot), MQUEUE_SLOT_STATUS );
uint32_t slot_stat = hmq_readl (dev, MQUEUE_BASE_IN(slot), MQUEUE_SLOT_STATUS );
return !(slot_stat & MQUEUE_SLOT_STATUS_FULL);
}
void do_tx(struct wrn_dev *dev, const wrn_message& msg, int slot )
{
// DBG("do_tx: slot %d size %d\n", slot, msg.size());
hmq_writel(dev, HMQ_IN(slot), MQUEUE_CMD_CLAIM, MQUEUE_SLOT_COMMAND);
hmq_writel(dev, MQUEUE_BASE_IN(slot), MQUEUE_CMD_CLAIM, MQUEUE_SLOT_COMMAND);
for(int i=0;i<msg.size();i++)
{
// DBG("%d: %x\n", i, msg[i]);
hmq_writel(dev, HMQ_IN(slot), msg[i], MQUEUE_SLOT_DATA_START + i * 4);
hmq_writel(dev, MQUEUE_BASE_IN(slot), msg[i], MQUEUE_SLOT_DATA_START + i * 4);
}
hmq_writel(dev, HMQ_IN(slot), MQUEUE_CMD_READY, MQUEUE_SLOT_COMMAND);
hmq_writel(dev, MQUEUE_BASE_IN(slot), MQUEUE_CMD_READY, MQUEUE_SLOT_COMMAND);
}
......@@ -344,22 +319,17 @@ int update_mqueues( struct wrn_dev * dev )
int slot;
int rx_limit = 5;
int got_sth = 0;
// outgoing path (from CPUs)
while(do_rx (dev, msg, slot) && rx_limit)
{
// DBG("RxLim %d\n", rx_limit);
rx_limit--;
got_sth = 1;
//DBG("slot %d rx %d words\n", slot, msg.size());
for (wrn_connmap::iterator i = dev->fds.begin(); i != dev->fds.end(); ++i)
{
wrn_buffer *buf = i->second->out;
if( buf && buf->slot == slot)
{
// DBG("-> queue to fd %d\n", i->first);
buf->lock( true );
//DBG("locked\n");
buf->process(msg);
buf->unlock();
......@@ -377,7 +347,6 @@ int update_mqueues( struct wrn_dev * dev )
{
buf->lock(true);
got_sth = 1;
// DBG("DoTX\n");
do_tx(dev, buf->pop(), buf->slot);
buf->unlock();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment