From 26e3885fbcc556ecd7231165048e6a994b5a00d9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 16 Oct 2016 02:33:36 -0400 Subject: [PATCH 001/211] mpmc_queue => queue --- include/villas/path.h | 2 +- include/villas/pool.h | 10 +++++----- include/villas/queue.h | 18 +++++++++--------- lib/path.c | 8 ++++---- lib/pool.c | 6 +++--- lib/queue.c | 22 +++++++++++----------- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index 801acf51d..fb01e5d23 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -42,7 +42,7 @@ struct path struct node *in; /**< Pointer to the incoming node */ - struct mpmc_queue queue; /**< A ring buffer for all received messages (unmodified) */ + struct queue queue; /**< A ring buffer for all received messages (unmodified) */ struct pool pool; /**< Memory pool for messages / samples. */ struct list destinations; /**< List of all outgoing nodes */ diff --git a/include/villas/pool.h b/include/villas/pool.h index c6ffcc466..4c0fc70f4 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -28,7 +28,7 @@ struct pool { size_t blocksz; /**< Length of a block in bytes */ size_t alignment; /**< Alignment of a block in bytes */ - struct mpmc_queue queue; /**< The queue which is used to keep track of free blocks */ + struct queue queue; /**< The queue which is used to keep track of free blocks */ }; #define INLINE static inline __attribute__((unused)) @@ -42,26 +42,26 @@ int pool_destroy(struct pool *p); /** Pop cnt values from the stack an place them in the array blocks */ INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt) { - return mpmc_queue_pull_many(&p->queue, blocks, cnt); + return queue_pull_many(&p->queue, blocks, cnt); } /** Push cnt values which are giving by the array values to the stack. */ INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) { - return mpmc_queue_push_many(&p->queue, blocks, cnt); + return queue_push_many(&p->queue, blocks, cnt); } /** Get a free memory block from pool. */ INLINE void * pool_get(struct pool *p) { void *ptr; - return mpmc_queue_pull(&p->queue, &ptr) == 1 ? ptr : NULL; + return queue_pull(&p->queue, &ptr) == 1 ? ptr : NULL; } /** Release a memory block back to the pool. */ INLINE int pool_put(struct pool *p, void *buf) { - return mpmc_queue_push(&p->queue, buf); + return queue_push(&p->queue, buf); } #endif /* _POOL_H_ */ \ No newline at end of file diff --git a/include/villas/queue.h b/include/villas/queue.h index bf2a6cac0..40baf1f17 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -42,12 +42,12 @@ #define CACHELINE_SIZE 64 typedef char cacheline_pad_t[CACHELINE_SIZE]; -struct mpmc_queue { +struct queue { cacheline_pad_t _pad0; /**< Shared area: all threads read */ struct memtype const * mem; size_t buffer_mask; - struct mpmc_queue_cell { + struct queue_cell { atomic_size_t sequence; void *data; } *buffer; @@ -64,24 +64,24 @@ struct mpmc_queue { }; /** Initialize MPMC queue */ -int mpmc_queue_init(struct mpmc_queue *q, size_t size, const struct memtype *mem); +int queue_init(struct queue *q, size_t size, const struct memtype *mem); /** Desroy MPMC queue and release memory */ -int mpmc_queue_destroy(struct mpmc_queue *q); +int queue_destroy(struct queue *q); /** Return estimation of current queue usage. * * Note: This is only an estimation and not accurate as long other * threads are performing operations. */ -size_t mpmc_queue_available(struct mpmc_queue *q); +size_t queue_available(struct queue *q); -int mpmc_queue_push(struct mpmc_queue *q, void *ptr); +int queue_push(struct queue *q, void *ptr); -int mpmc_queue_pull(struct mpmc_queue *q, void **ptr); +int queue_pull(struct queue *q, void **ptr); -int mpmc_queue_push_many(struct mpmc_queue *q, void *ptr[], size_t cnt); +int queue_push_many(struct queue *q, void *ptr[], size_t cnt); -int mpmc_queue_pull_many(struct mpmc_queue *q, void *ptr[], size_t cnt); +int queue_pull_many(struct queue *q, void *ptr[], size_t cnt); #endif /* _MPMC_QUEUE_H_ */ \ No newline at end of file diff --git a/lib/path.c b/lib/path.c index b783c816f..69667cbcc 100644 --- a/lib/path.c +++ b/lib/path.c @@ -26,7 +26,7 @@ static void path_write(struct path *p, bool resend) int sent, tosend, available, released; struct sample *smps[n->vectorize]; - available = mpmc_queue_pull_many(&p->queue, (void **) smps, cnt); + available = queue_pull_many(&p->queue, (void **) smps, cnt); if (available < cnt) warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); @@ -108,7 +108,7 @@ static void * path_run(void *arg) p->skipped += recv - enqueue; } - enqueued = mpmc_queue_push_many(&p->queue, (void **) smps, enqueue); + enqueued = queue_push_many(&p->queue, (void **) smps, enqueue); if (enqueue != enqueued) warn("Failed to enqueue %u samples for path %s", enqueue - enqueued, path_name(p)); @@ -219,7 +219,7 @@ int path_prepare(struct path *p) if (ret) error("Failed to allocate memory pool for path"); - ret = mpmc_queue_init(&p->queue, p->queuelen, &memtype_hugepage); + ret = queue_init(&p->queue, p->queuelen, &memtype_hugepage); if (ret) error("Failed to initialize queue for path"); @@ -233,7 +233,7 @@ void path_destroy(struct path *p) list_destroy(&p->destinations, NULL, false); list_destroy(&p->hooks, NULL, true); - mpmc_queue_destroy(&p->queue); + queue_destroy(&p->queue); pool_destroy(&p->pool); free(p->_name); diff --git a/lib/pool.c b/lib/pool.c index 90317bd9e..156200c5a 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -26,17 +26,17 @@ int pool_init(struct pool *p, size_t blocksz, size_t cnt, const struct memtype * else debug(DBG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); - mpmc_queue_init(&p->queue, cnt, m); + queue_init(&p->queue, cnt, m); for (int i = 0; i < cnt; i++) - mpmc_queue_push(&p->queue, (char *) p->buffer + i * p->blocksz); + queue_push(&p->queue, (char *) p->buffer + i * p->blocksz); return 0; } int pool_destroy(struct pool *p) { - mpmc_queue_destroy(&p->queue); + queue_destroy(&p->queue); return memory_free(p->mem, p->buffer, p->len); } \ No newline at end of file diff --git a/lib/queue.c b/lib/queue.c index 136a7d263..1d1b797bd 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -34,7 +34,7 @@ #include "queue.h" /** Initialize MPMC queue */ -int mpmc_queue_init(struct mpmc_queue *q, size_t size, const struct memtype *mem) +int queue_init(struct queue *q, size_t size, const struct memtype *mem) { /* Queue size must be 2 exponent */ if ((size < 2) || ((size & (size - 1)) != 0)) @@ -55,7 +55,7 @@ int mpmc_queue_init(struct mpmc_queue *q, size_t size, const struct memtype *mem return 0; } -int mpmc_queue_destroy(struct mpmc_queue *q) +int queue_destroy(struct queue *q) { return memory_free(q->mem, q->buffer, (q->buffer_mask + 1) * sizeof(sizeof(q->buffer[0]))); } @@ -65,15 +65,15 @@ int mpmc_queue_destroy(struct mpmc_queue *q) * Note: This is only an estimation and not accurate as long other * threads are performing operations. */ -size_t mpmc_queue_available(struct mpmc_queue *q) +size_t queue_available(struct queue *q) { return atomic_load_explicit(&q->tail, memory_order_relaxed) - atomic_load_explicit(&q->head, memory_order_relaxed); } -int mpmc_queue_push(struct mpmc_queue *q, void *ptr) +int queue_push(struct queue *q, void *ptr) { - struct mpmc_queue_cell *cell; + struct queue_cell *cell; size_t pos, seq; intptr_t diff; @@ -99,9 +99,9 @@ int mpmc_queue_push(struct mpmc_queue *q, void *ptr) return 1; } -int mpmc_queue_pull(struct mpmc_queue *q, void **ptr) +int queue_pull(struct queue *q, void **ptr) { - struct mpmc_queue_cell *cell; + struct queue_cell *cell; size_t pos, seq; intptr_t diff; @@ -128,13 +128,13 @@ int mpmc_queue_pull(struct mpmc_queue *q, void **ptr) return 1; } -int mpmc_queue_push_many(struct mpmc_queue *q, void *ptr[], size_t cnt) +int queue_push_many(struct queue *q, void *ptr[], size_t cnt) { int ret; size_t i; for (i = 0; i < cnt; i++) { - ret = mpmc_queue_push(q, ptr[i]); + ret = queue_push(q, ptr[i]); if (!ret) break; } @@ -142,13 +142,13 @@ int mpmc_queue_push_many(struct mpmc_queue *q, void *ptr[], size_t cnt) return i; } -int mpmc_queue_pull_many(struct mpmc_queue *q, void *ptr[], size_t cnt) +int queue_pull_many(struct queue *q, void *ptr[], size_t cnt) { int ret; size_t i; for (i = 0; i < cnt; i++) { - ret = mpmc_queue_pull(q, &ptr[i]); + ret = queue_pull(q, &ptr[i]); if (!ret) break; } From 07d4c623e80ee2fd8492c4d17c5861244bf6296f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 16 Oct 2016 02:33:57 -0400 Subject: [PATCH 002/211] fix deployment of web site --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d0ef8281f..449be5384 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -101,7 +101,7 @@ integration: website: stage: deploy script: - - rsync web/ $DEPLOY_PATH/ + - rsync -r web/ $DEPLOY_PATH/ only: - develop tags: From 626ddc2043b01becc64f2a8c6a948d8dda64f2d8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 16 Oct 2016 13:12:08 -0400 Subject: [PATCH 003/211] added preliminary draft for new websocket msg format --- include/villas/webmsg_format.h | 101 +++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 include/villas/webmsg_format.h diff --git a/include/villas/webmsg_format.h b/include/villas/webmsg_format.h new file mode 100644 index 000000000..3873d4470 --- /dev/null +++ b/include/villas/webmsg_format.h @@ -0,0 +1,101 @@ +/** Binary websocket message format + * + * @file + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#ifndef _WEBMSG_FORMAT_H_ +#define _WEBMSG_FORMAT_H_ + +#include + +#ifdef __linux__ + #define _BSD_SOURCE 1 + #include +#elif defined(__PPC__) /* Xilinx toolchain */ + #include +#endif + +/** The current version number for the message format */ +#define WEBMSG_VERSION 1 + +/** @todo Implement more message types */ +#define WEBMSG_TYPE_DATA 0 /**< Message contains float values */ +#define WEBMSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ +#define WEBMSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ + +#define WEBMSG_ENDIAN_LITTLE 0 /**< Message values are in little endian format (float too!) */ +#define WEBMSG_ENDIAN_BIG 1 /**< Message values are in bit endian format */ + +#if BYTE_ORDER == LITTLE_ENDIAN + #define WEBMSG_ENDIAN_HOST MSG_ENDIAN_LITTLE +#elif BYTE_ORDER == BIG_ENDIAN + #define WEBMSG_ENDIAN_HOST MSG_ENDIAN_BIG +#else + #error "Unknown byte order!" +#endif + +/** The total size in bytes of a message */ +#define WEBMSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) + +/** The length of \p values values in bytes. */ +#define WEBMSG_DATA_LEN(values) (sizeof(float) * (values)) + +/** The offset to the first data value in a message. */ +#define WEBMSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) + +/** Initialize a message with default values */ +#define WEBMSG_INIT(len, seq) (struct msg) {\ + .version = MSG_VERSION, \ + .type = MSG_TYPE_DATA, \ + .endian = MSG_ENDIAN_HOST, \ + .length = len, \ + .sequence = seq \ +} + +/** The timestamp of a message in struct timespec format */ +#define WEBMSG_TS(msg) (struct timespec) {\ + .tv_sec = (msg)->ts.sec, \ + .tv_nsec = (msg)->ts.nsec \ +} + +/** This message format is used by all clients + * + * @diafile msg_format.dia + **/ +struct webmsg +{ +#if BYTE_ORDER == BIG_ENDIAN + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */ + unsigned rsvd1 : 1; /**< Reserved bits */ +#elif BYTE_ORDER == LITTLE_ENDIAN + unsigned rsvd1 : 1; /**< Reserved bits */ + unsigned endian : 1; /**< Specifies the byteorder of the message (see MSG_ENDIAN_*) */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ +#endif + + uint8_t src_node; /**< Reserved bits */ + + uint16_t length; /**< The number of values in msg::data[]. Endianess is specified in msg::endian. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. Endianess is specified in msg::endian. */ + + /** A timestamp per message. Endianess is specified in msg::endian. */ + struct { + uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ + } ts; + + /** The message payload. Endianess is specified in msg::endian. */ + union { + float f; /**< Floating point values (note msg::endian) */ + uint32_t i; /**< Integer values (note msg::endian) */ + } data[]; +} __attribute__((packed)); + +#endif /* _WEBMSG_FORMAT_H_ */ From cf59a485abd95c3d856acac4b2b8948e05b55390 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:25:05 -0400 Subject: [PATCH 004/211] rdtscp => rdtsc --- include/villas/utils.h | 4 ++-- lib/utils.c | 5 +++-- src/fpga-bench-overruns.c | 4 ++-- src/fpga-bench.c | 16 ++++++++-------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/villas/utils.h b/include/villas/utils.h index 6664b2232..82b7cabb7 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -204,11 +204,11 @@ void printb(void *mem, size_t len); void printdw(void *mem, size_t len); /** Get CPU timestep counter */ -__attribute__((always_inline)) static inline uint64_t rdtscp() +__attribute__((always_inline)) static inline uint64_t rdtsc() { uint64_t tsc; - __asm__ ("rdtscp;" + __asm__ ("rdtsc;" "shl $32, %%rdx;" "or %%rdx,%%rax" : "=a" (tsc) diff --git a/lib/utils.c b/lib/utils.c index 66512c3bd..eff72a954 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -370,12 +370,13 @@ void rdtsc_sleep(uint64_t nanosecs, uint64_t start) { uint64_t cycles; + /** @todo Replace the hard coded CPU clock frequency */ cycles = (double) nanosecs / (1e9 / 3392389000); if (start == 0) - start = rdtscp(); + start = rdtsc(); do { __asm__("nop"); - } while (rdtscp() - start < cycles); + } while (rdtsc() - start < cycles); } \ No newline at end of file diff --git a/src/fpga-bench-overruns.c b/src/fpga-bench-overruns.c index f161c7696..73346b5e9 100644 --- a/src/fpga-bench-overruns.c +++ b/src/fpga-bench-overruns.c @@ -115,9 +115,9 @@ int fpga_benchmark_overruns(struct fpga *f) for (int i = 0; i < runs + BENCH_WARMUP; i++) { dma_read(dm, mem.base_phys, 0x200); - start = rdtscp(); + start = rdtsc(); lapack_workload(p, A); - stop = rdtscp(); + stop = rdtsc(); dma_read_complete(dm, NULL, NULL); diff --git a/src/fpga-bench.c b/src/fpga-bench.c index 2ab2523a0..1de87f1f3 100644 --- a/src/fpga-bench.c +++ b/src/fpga-bench.c @@ -108,7 +108,7 @@ int fpga_benchmark_jitter(struct fpga *f) XTmrCtr_SetResetValue(xtmr, 0, period * FPGA_AXI_HZ); XTmrCtr_Start(xtmr, 0); - uint64_t end, start = rdtscp(); + uint64_t end, start = rdtsc(); for (int i = 0; i < runs; i++) { uint64_t cnt = intc_wait(f->intc, tmr->irq); if (cnt != 1) @@ -117,7 +117,7 @@ int fpga_benchmark_jitter(struct fpga *f) /* Ackowledge IRQ */ XTmrCtr_WriteReg((uintptr_t) f->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET, XTmrCtr_ReadReg((uintptr_t) f->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET)); - end = rdtscp(); + end = rdtsc(); hist[i] = end - start; start = end; } @@ -157,11 +157,11 @@ int fpga_benchmark_latency(struct fpga *f) error("Failed to enable interrupts"); for (int i = 0; i < runs; i++) { - start = rdtscp(); + start = rdtsc(); XIntc_Out32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET, 0x100); intc_wait(f->intc, 8); - end = rdtscp(); + end = rdtsc(); hist[i] = end - start; } @@ -239,7 +239,7 @@ int fpga_benchmark_datamover(struct fpga *f) uint64_t runs = BENCH_RUNS >> exp; for (int i = 0; i < runs + BENCH_WARMUP; i++) { - start = rdtscp(); + start = rdtsc(); #if BENCH_DM == 1 ssize_t ret; @@ -255,7 +255,7 @@ int fpga_benchmark_datamover(struct fpga *f) if (ret) error("DMA ping pong failed"); #endif - stop = rdtscp(); + stop = rdtsc(); if (memcmp(src.base_virt, dst.base_virt, len)) warn("Compare failed"); @@ -304,13 +304,13 @@ int fpga_benchmark_memcpy(struct fpga *f) uint64_t runs = (BENCH_RUNS << 2) >> exp; for (int i = 0; i < runs + BENCH_WARMUP; i++) { - start = rdtscp(); + start = rdtsc(); for (int j = 0; j < len / 4; j++) // mapi[j] = j; // write dummy += mapi[j]; // read - end = rdtscp(); + end = rdtsc(); if (i > BENCH_WARMUP) total += end - start; From bb50cc843e04668cee9c894b4dd0de600adcc394 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:25:52 -0400 Subject: [PATCH 005/211] added unit test for MPMC queue --- tests/Makefile.inc | 2 +- tests/queue.c | 321 +++++++++++++++++++++++++++++++++++++++++-- thirdparty/criterion | 2 +- 3 files changed, 309 insertions(+), 16 deletions(-) diff --git a/tests/Makefile.inc b/tests/Makefile.inc index b701f5772..facbef13f 100644 --- a/tests/Makefile.inc +++ b/tests/Makefile.inc @@ -3,7 +3,7 @@ TEST_OBJS = $(patsubst %.c,$(BUILDDIR)/%.o,$(TEST_SRCS)) TEST_CFLAGS = $(CFLAGS) TEST_LDFLAGS = $(LDFLAGS) -Wl,-rpath,'$$ORIGIN' -TEST_LDLIBS = $(LDLIBS) -lcriterion -lvillas +TEST_LDLIBS = $(LDLIBS) -lcriterion -lvillas -pthread tests: $(BUILDDIR)/testsuite diff --git a/tests/queue.c b/tests/queue.c index 1c02306ba..9d30a1b4f 100644 --- a/tests/queue.c +++ b/tests/queue.c @@ -1,25 +1,318 @@ -/** Unit tests for MPMC queue - * - * @author Steffen Vogel - * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - *********************************************************************************/ +#include +#include +#include +#include +#include +#include #include +#include +#include +#include "utils.h" #include "queue.h" +#include "memory.h" -Test(queue, singleThreaded) +#define SIZE (1 << 10) + +static struct queue q; + +struct param { + int volatile start; + int thread_count; + int queue_size; + int iter_count; + int batch_size; + void * (*thread_func)(void *); + struct queue queue; + const struct memtype *memtype; +}; + +/** Get thread id as integer + * In contrast to pthread_t which is an opaque type */ +#ifdef __linux__ + #include +#endif + +uint64_t thread_get_id() { -/* struct queue q; +#ifdef __MACH__ + uint64_t id; + pthread_threadid_np(pthread_self(), &id); + return id; +#elif defined(SYS_gettid) + return (int) syscall(SYS_gettid); +#endif + return -1; +} + +/** Sleep, do nothing */ +__attribute__((always_inline)) static inline void nop() +{ + __asm__("rep nop;"); +} + +static void * producer(void *ctx) +{ + int ret; + struct param *p = (struct param *) ctx; - queue_init(&q, 100, &memtype_heap); + srand((unsigned) time(0) + thread_get_id()); + size_t nops = rand() % 1000; - srand(1337); + /** @todo Criterion cr_log() is broken for multi-threaded programs */ + //cr_log_info("producer: tid = %lu", thread_get_id()); + + /* Wait for global start signal */ + while (p->start == 0) + pthread_yield(); - for (int i = 0; i < 100; i++) - queue_push(&q, &) + //cr_log_info("producer: wait for %zd nops", nops); - queue_destroy(&q);*/ + /* Wait for a random time */ + for (size_t i = 0; i != nops; i += 1) + nop(); + + //cr_log_info("producer: start pushing"); + + /* Enqueue */ + for (unsigned long count = 0; count < p->iter_count; count++) { + do { + ret = queue_push(&p->queue, (void *) count); + pthread_yield(); + } while (ret != 1); + } + + //cr_log_info("producer: finished"); + + return NULL; +} + +static void * consumer(void *ctx) +{ + int ret; + struct param *p = (struct param *) ctx; + + srand((unsigned) time(0) + thread_get_id()); + size_t nops = rand() % 1000; + + //cr_log_info("consumer: tid = %lu", thread_get_id()); + + /* Wait for global start signal */ + while (p->start == 0) + pthread_yield(); + + //cr_log_info("consumer: wait for %zd nops", nops); + + /* Wait for a random time */ + for (size_t i = 0; i != nops; i += 1) + nop(); + + //cr_log_info("consumer: start pulling"); + + /* Dequeue */ + for (unsigned long count = 0; count < p->iter_count; count++) { + void *ptr; + + do { + ret = queue_pull(&p->queue, &ptr); + } while (ret != 1); + + //cr_log_info("consumer: %lu\n", count); + + //cr_assert_eq((intptr_t) ptr, count); + } + + //cr_log_info("consumer: finished"); + + return NULL; +} + +void * producer_consumer(void *ctx) +{ + struct param *p = (struct param *) ctx; + + srand((unsigned) time(0) + thread_get_id()); + size_t nops = rand() % 1000; + + /* Wait for global start signal */ + while (p->start == 0) + pthread_yield(); + + /* Wait for a random time */ + for (size_t i = 0; i != nops; i += 1) + nop(); + + for (int iter = 0; iter < p->iter_count; ++iter) { + for (size_t i = 0; i < p->batch_size; i++) { + void *ptr = (void *) (iter * p->batch_size + i); + while (!queue_push(&p->queue, ptr)) + pthread_yield(); /* queue full, let other threads proceed */ + } + + for (size_t i = 0; i < p->batch_size; i++) { + void *ptr; + while (!queue_pull(&p->queue, &ptr)) + pthread_yield(); /* queue empty, let other threads proceed */ + } + } + + return 0; +} + +void * producer_consumer_many(void *ctx) +{ + struct param *p = (struct param *) ctx; + + srand((unsigned) time(0) + thread_get_id()); + size_t nops = rand() % 1000; + + /* Wait for global start signal */ + while (p->start == 0) + pthread_yield(); + + /* Wait for a random time */ + for (size_t i = 0; i != nops; i += 1) + nop(); + + void *ptrs[p->batch_size]; + + for (int iter = 0; iter < p->iter_count; ++iter) { + for (size_t i = 0; i < p->batch_size; i++) + ptrs[i] = (void *) (iter * p->batch_size + i); + + int pushed = 0; + do { + pushed += queue_push_many(&p->queue, &ptrs[pushed], p->batch_size - pushed); + if (pushed != p->batch_size) + pthread_yield(); /* queue full, let other threads proceed */ + } while (pushed < p->batch_size); + + int pulled = 0; + do { + pulled += queue_pull_many(&p->queue, &ptrs[pulled], p->batch_size - pulled); + if (pulled != p->batch_size) + pthread_yield(); /* queue empty, let other threads proceed */ + } while (pulled < p->batch_size); + } + + return 0; +} + +Test(queue, single_threaded) +{ + int ret; + struct param p = { + .iter_count = 1 << 8, + .queue_size = 1 << 10, + .start = 1 /* we start immeadiatly */ + }; + + ret = queue_init(&p.queue, p.queue_size, &memtype_heap); + cr_assert_eq(ret, 0, "Failed to create queue"); + + producer(&p); + consumer(&p); + + cr_assert_eq(queue_available(&q), 0); + + ret = queue_destroy(&p.queue); + cr_assert_eq(ret, 0, "Failed to create queue"); +} + +ParameterizedTestParameters(queue, multi_threaded) +{ + static struct param params[] = { + { + .iter_count = 1 << 12, + .queue_size = 1 << 9, + .thread_count = 32, + .thread_func = producer_consumer_many, + .batch_size = 10, + .memtype = &memtype_heap + }, { + .iter_count = 1 << 8, + .queue_size = 1 << 9, + .thread_count = 4, + .thread_func = producer_consumer_many, + .batch_size = 100, + .memtype = &memtype_heap + }, { + .iter_count = 1 << 16, + .queue_size = 1 << 9, + .thread_count = 16, + .thread_func = producer_consumer_many, + .batch_size = 100, + .memtype = &memtype_heap + }, { + .iter_count = 1 << 8, + .queue_size = 1 << 9, + .thread_count = 4, + .thread_func = producer_consumer_many, + .batch_size = 10, + .memtype = &memtype_heap + }, { + .iter_count = 1 << 16, + .queue_size = 1 << 9, + .thread_count = 16, + .thread_func = producer_consumer, + .batch_size = 10, + .memtype = &memtype_hugepage + } + }; + + return cr_make_param_array(struct param, params, ARRAY_LEN(params)); +} + +ParameterizedTest(struct param *p, queue, multi_threaded, .timeout = 10) +{ + int ret, cycpop; + + pthread_t threads[p->thread_count]; + + p->start = 0; + + ret = queue_init(&p->queue, p->queue_size, &memtype_heap); + cr_assert_eq(ret, 0, "Failed to create queue"); + + uint64_t start_tsc_time, end_tsc_time; + + for (int i = 0; i < p->thread_count; ++i) + pthread_create(&threads[i], NULL, p->thread_func, &p); + + sleep(1); + + start_tsc_time = rdtsc(); + p->start = 1; + + for (int i = 0; i < p->thread_count; ++i) + pthread_join(threads[i], NULL); + + end_tsc_time = rdtsc(); + cycpop = (end_tsc_time - start_tsc_time) / p->iter_count; + + if (cycpop < 400) + cr_log_info("cycles/op: %u\n", cycpop); + else + cr_log_warn("cycles/op are very high (%u). Are you running on a a hypervisor?\n", cycpop); + + cr_assert_eq(queue_available(&q), 0); + + ret = queue_destroy(&p->queue); + cr_assert_eq(ret, 0, "Failed to create queue"); +} + +Test(queue, init_destroy) +{ + int ret; + struct queue q; + + ret = queue_init(&q, 100, &memtype_heap); + cr_assert_eq(ret, -1); /* Should fail as size is not 2^x */ + + ret = queue_init(&q, 1024, &memtype_heap); + cr_assert_eq(ret, 0); /* Should succeed */ + + ret = queue_destroy(&q); + cr_assert_eq(ret, 0); /* Should succeed */ } \ No newline at end of file diff --git a/thirdparty/criterion b/thirdparty/criterion index 5b0f2b129..1b687a9f6 160000 --- a/thirdparty/criterion +++ b/thirdparty/criterion @@ -1 +1 @@ -Subproject commit 5b0f2b129046955c004ff56ab2caada5b55ba8e3 +Subproject commit 1b687a9f6a0e51c9e9b0a047e1fcd6c94de7a080 From 8e88493fb86532a7c4c3936c946ee4e7357ba6cb Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:33:18 -0400 Subject: [PATCH 006/211] fix continuous integration --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 408766244..54ec74dc8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,7 +82,7 @@ COPY thirdparty/libwebsockets /tmp/libwebsockets RUN mkdir -p /tmp/libwebsockets/build && cd /tmp/libwebsockets/build && cmake .. && make install # Cleanup intermediate files from builds -RUN rm -rf /tmp +RUN rm -rf /tmp/* WORKDIR /villas From 6e13d5a895b2aa6d66e4d12c812bc0288bdbb45d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:34:27 -0400 Subject: [PATCH 007/211] add debug statements to memory functions --- include/villas/log.h | 1 + lib/memory.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/villas/log.h b/include/villas/log.h index b94ccb891..c57d686bf 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -38,6 +38,7 @@ enum debug_facilities { DBG_CONFIG = (1 << 10), DBG_HOOK = (1 << 11), DBG_PATH = (1 << 12), + DBG_MEM = (1 << 13), /* Node-types */ DBG_SOCKET = (1 << 16), diff --git a/lib/memory.c b/lib/memory.c index e6501bf01..df4eccd7e 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -19,23 +19,20 @@ void * memory_alloc(const struct memtype *m, size_t len) { + debug(DBG_MEM | 2, "Allocating %zu byte of %s memory", len, m->name); return m->alloc(len); } void * memory_alloc_aligned(const struct memtype *m, size_t len, size_t alignment) { - warn("memory_alloc_aligned: not implemented yet!"); - return memory_alloc(m, len); -} - -void * memory_aligned_alloc(const struct memtype *m, size_t len, size_t align) -{ - warn("memory_aligned_alloc: not implemented yet. Falling back to unaligned version."); + debug(DBG_MEM | 2, "Allocating %zu byte of %zu-byte-aligned %s memory", len, alignment, m->name); + warn("%s: not implemented yet!", __FUNCTION__); return memory_alloc(m, len); } int memory_free(const struct memtype *m, void *ptr, size_t len) { + debug(DBG_MEM | 2, "Releasing %zu bytes of %s memory", len, m->name); return m->free(ptr, len); } @@ -85,7 +82,7 @@ const struct memtype memtype_hugepage = { .flags = MEMORY_MMAP | MEMORY_HUGEPAGE, .alloc = memory_hugepage_alloc, .free = memory_hugepage_free, - .alignment = 1 << 21 /* 2 MiB hugepage */ + .alignment = 21 /* 2 MiB hugepage */ }; /** @todo */ @@ -93,5 +90,5 @@ const struct memtype memtype_dma = { .name = "dma", .flags = MEMORY_DMA | MEMORY_MMAP, .alloc = NULL, .free = NULL, - .alignment = 1 << 12 + .alignment = 12 }; From 09f486bc322f944e6be13db0b5ce351d0d6bbe69 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:35:08 -0400 Subject: [PATCH 008/211] timout for timing unit tests --- tests/timing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/timing.c b/tests/timing.c index b4ef56813..82fb8bf6f 100644 --- a/tests/timing.c +++ b/tests/timing.c @@ -76,7 +76,7 @@ Test(timing, time_to_from_double) cr_assert_float_eq(dbl, ref, 1e-9); } -Test(timing, timerfd_create_rate) +Test(timing, timerfd_create_rate, .timeout = 20) { struct timespec start, end; @@ -100,7 +100,7 @@ Test(timing, timerfd_create_rate) close(tfd); } -Test(timing, timerfd_wait_until) +Test(timing, timerfd_wait_until, .timeout = 1) { int tfd = timerfd_create(CLOCK_REALTIME, 0); From 7a7b36e67811452000b6fbe8cd60c592f898aac4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 19 Oct 2016 01:35:41 -0400 Subject: [PATCH 009/211] some fixes for memory pool --- include/villas/pool.h | 5 ++--- lib/pool.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/villas/pool.h b/include/villas/pool.h index 4c0fc70f4..49f2f1c9a 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -15,8 +15,7 @@ #include #include "queue.h" - -struct memtype; +#include "memory.h" /** A thread-safe memory pool */ struct pool { @@ -34,7 +33,7 @@ struct pool { #define INLINE static inline __attribute__((unused)) /** Initiazlize a pool */ -int pool_init(struct pool *p, size_t blocksz, size_t alignment, const struct memtype *mem); +int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype *mem); /** Destroy and release memory used by pool. */ int pool_destroy(struct pool *p); diff --git a/lib/pool.c b/lib/pool.c index 156200c5a..955b8b77a 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -12,8 +12,10 @@ #include "memory.h" #include "kernel/kernel.h" -int pool_init(struct pool *p, size_t blocksz, size_t cnt, const struct memtype *m) +int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype *m) { + int ret; + /* Make sure that we use a block size that is aligned to the size of a cache line */ p->alignment = kernel_get_cacheline_size(); p->blocksz = blocksz * CEIL(blocksz, p->alignment); @@ -25,12 +27,14 @@ int pool_init(struct pool *p, size_t blocksz, size_t cnt, const struct memtype * serror("Failed to allocate memory for memory pool"); else debug(DBG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); - - queue_init(&p->queue, cnt, m); + + ret = queue_init(&p->queue, cnt, m); + if (ret) + return ret; for (int i = 0; i < cnt; i++) queue_push(&p->queue, (char *) p->buffer + i * p->blocksz); - + return 0; } From 64ee734dc20253ca24f029d9f7c82c2542aba03d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 18:01:06 -0400 Subject: [PATCH 010/211] remove fixed-rate sending (will be replaced by new register node-type) --- include/villas/path.h | 8 ++----- lib/cfg.c | 2 -- lib/path.c | 53 ++++--------------------------------------- 3 files changed, 7 insertions(+), 56 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index fb01e5d23..654131e2e 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -42,7 +42,7 @@ struct path struct node *in; /**< Pointer to the incoming node */ - struct queue queue; /**< A ring buffer for all received messages (unmodified) */ + struct queue queue; /**< A ring buffer for all received messages (unmodified) */ struct pool pool; /**< Memory pool for messages / samples. */ struct list destinations; /**< List of all outgoing nodes */ @@ -51,11 +51,8 @@ struct path int samplelen; /**< Maximum number of values per sample for this path. */ int queuelen; /**< Size of sample queue for this path. */ int enabled; /**< Is this path enabled */ - int tfd; /**< Timer file descriptor for fixed rate sending */ - double rate; /**< Send messages with a fixed rate over this path */ - pthread_t recv_tid; /**< The thread id for this path */ - pthread_t sent_tid; /**< A second thread id for fixed rate sending thread */ + pthread_t tid; /**< The thread id for this path */ config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ @@ -74,7 +71,6 @@ struct path uintmax_t invalid; /**< Counter for invalid messages */ uintmax_t skipped; /**< Counter for skipped messages due to hooks */ uintmax_t dropped; /**< Counter for dropped messages due to reordering */ - uintmax_t overrun; /**< Counter of overruns for fixed-rate sending */ /** @} */ }; diff --git a/lib/cfg.c b/lib/cfg.c index 33fe11ed6..84fbfd35f 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -201,8 +201,6 @@ int cfg_parse_path(config_setting_t *cfg, reverse = 0; if (!config_setting_lookup_bool(cfg, "enabled", &p->enabled)) p->enabled = 1; - if (!config_setting_lookup_float(cfg, "rate", &p->rate)) - p->rate = 0; /* disabled */ p->cfg = cfg; diff --git a/lib/path.c b/lib/path.c index 69667cbcc..ec8e100ba 100644 --- a/lib/path.c +++ b/lib/path.c @@ -51,32 +51,7 @@ static void path_write(struct path *p, bool resend) } } -/** Send messages asynchronously */ -static void * path_run_async(void *arg) -{ - struct path *p = arg; - - /* Block until 1/p->rate seconds elapsed */ - for (;;) { - /* Check for overruns */ - uint64_t expir = timerfd_wait(p->tfd); - if (expir == 0) - perror("Failed to wait for timer"); - else if (expir > 1) { - p->overrun += expir; - warn("Overrun detected for path: overruns=%" PRIu64, expir); - } - - if (hook_run(p, NULL, 0, HOOK_ASYNC)) - continue; - - path_write(p, true); - } - - return NULL; -} - -/** Receive messages */ +/** Main thread function per path: receive -> sent messages */ static void * path_run(void *arg) { struct path *p = arg; @@ -116,9 +91,7 @@ static void * path_run(void *arg) debug(DBG_PATH | 3, "Enqueuing %u samples to queue of path %s", enqueue, path_name(p)); - /* At fixed rate mode, messages are send by another (asynchronous) thread */ - if (p->rate == 0) - path_write(p, false); + path_write(p); } return NULL; @@ -128,25 +101,16 @@ int path_start(struct path *p) { int ret; - info("Starting path: %s (#hooks=%zu, rate=%.1f)", - path_name(p), list_length(&p->hooks), p->rate); + info("Starting path: %s (#hooks=%zu)", + path_name(p), list_length(&p->hooks)); ret = hook_run(p, NULL, 0, HOOK_PATH_START); if (ret) return -1; - /* At fixed rate mode, we start another thread for sending */ - if (p->rate) { - p->tfd = timerfd_create_rate(p->rate); - if (p->tfd < 0) - serror("Failed to create timer"); - - pthread_create(&p->sent_tid, NULL, &path_run_async, p); - } - p->state = PATH_RUNNING; - return pthread_create(&p->recv_tid, NULL, &path_run, p); + return pthread_create(&p->tid, NULL, &path_run, p); } int path_stop(struct path *p) @@ -156,13 +120,6 @@ int path_stop(struct path *p) pthread_cancel(p->recv_tid); pthread_join(p->recv_tid, NULL); - if (p->rate) { - pthread_cancel(p->sent_tid); - pthread_join(p->sent_tid, NULL); - - close(p->tfd); - } - p->state = PATH_STOPPED; if (hook_run(p, NULL, 0, HOOK_PATH_STOP)) From bad1dc953adda594b00d7c16c3cb1686e74aa61b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 18:01:42 -0400 Subject: [PATCH 011/211] fix Doxygen commenting style --- include/villas/kernel/pci.h | 2 +- include/villas/nodes/socket.h | 4 ++-- include/villas/queue.h | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h index 747f5c488..82906b9d2 100644 --- a/include/villas/kernel/pci.h +++ b/include/villas/kernel/pci.h @@ -31,7 +31,7 @@ struct pci_dev { }; struct pci { - struct list devices; /**> List of available PCI devices in the system (struct pci_dev) */ + struct list devices; /**< List of available PCI devices in the system (struct pci_dev) */ }; /** Initialize Linux PCI handle. diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 64c1dd82e..044e76de9 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -29,8 +29,8 @@ enum socket_layer { }; enum socket_header { - SOCKET_HEADER_DEFAULT, /**> Default header in the payload, (see msg_format.h) */ - SOCKET_HEADER_GTNET_SKT /**> No header in the payload, same as HDR_NONE*/ + SOCKET_HEADER_DEFAULT, /**< Default header in the payload, (see msg_format.h) */ + SOCKET_HEADER_GTNET_SKT /**< No header in the payload, same as HDR_NONE*/ }; union sockaddr_union { diff --git a/include/villas/queue.h b/include/villas/queue.h index 40baf1f17..50fa5aff9 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -52,15 +52,15 @@ struct queue { void *data; } *buffer; - cacheline_pad_t _pad1; /**> Producer area: only producers read & write */ + cacheline_pad_t _pad1; /**< Producer area: only producers read & write */ - atomic_size_t tail; /**> Queue tail pointer */ + atomic_size_t tail; /**< Queue tail pointer */ - cacheline_pad_t _pad2; /**> Consumer area: only consumers read & write */ + cacheline_pad_t _pad2; /**< Consumer area: only consumers read & write */ - atomic_size_t head; /**> Queue head pointer */ + atomic_size_t head; /**< Queue head pointer */ - cacheline_pad_t _pad3; /**> @todo Why needed? */ + cacheline_pad_t _pad3; /**< @todo Why needed? */ }; /** Initialize MPMC queue */ From 69a16b2ac70e0816f3663b8b4f2584d56c25e727 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 18:04:18 -0400 Subject: [PATCH 012/211] added a couple of states to the path FSM --- include/villas/path.h | 6 ++++-- lib/path.c | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index 654131e2e..abd1dfbc2 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -35,9 +35,11 @@ struct path { enum { PATH_INVALID, /**< Path is invalid. */ - PATH_CREATED, /**< Path has been created. */ + PATH_CREATED, /**< Path has been created: lists initialized */ + PATH_INITIALIZED, /**< Path queues, memory pools & hook system initialized. */ PATH_RUNNING, /**< Path is currently running. */ - PATH_STOPPED /**< Path has been stopped. */ + PATH_STOPPED, /**< Path has been stopped. */ + PATH_DESTROYED /**< Path is destroyed. */ } state; /**< Path state */ struct node *in; /**< Pointer to the incoming node */ diff --git a/lib/path.c b/lib/path.c index ec8e100ba..dde5b0e0e 100644 --- a/lib/path.c +++ b/lib/path.c @@ -120,11 +120,11 @@ int path_stop(struct path *p) pthread_cancel(p->recv_tid); pthread_join(p->recv_tid, NULL); - p->state = PATH_STOPPED; - if (hook_run(p, NULL, 0, HOOK_PATH_STOP)) return -1; + p->state = PATH_STOPPED; + return 0; } @@ -179,6 +179,8 @@ int path_prepare(struct path *p) ret = queue_init(&p->queue, p->queuelen, &memtype_hugepage); if (ret) error("Failed to initialize queue for path"); + + p->state = PATH_INITIALIZED; return 0; } @@ -192,6 +194,8 @@ void path_destroy(struct path *p) queue_destroy(&p->queue); pool_destroy(&p->pool); + + p->state = PATH_DESTROYED; free(p->_name); } From de1058cbd66cab9483b7c5fef9dde4c2f7b0d4e5 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 18:05:56 -0400 Subject: [PATCH 013/211] merging path_write() into path_run() --- lib/path.c | 61 +++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/lib/path.c b/lib/path.c index dde5b0e0e..f94feeea3 100644 --- a/lib/path.c +++ b/lib/path.c @@ -19,38 +19,6 @@ #include "pool.h" #include "queue.h" -static void path_write(struct path *p, bool resend) -{ - list_foreach(struct node *n, &p->destinations) { - int cnt = n->vectorize; - int sent, tosend, available, released; - struct sample *smps[n->vectorize]; - - available = queue_pull_many(&p->queue, (void **) smps, cnt); - if (available < cnt) - warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); - - if (available == 0) - continue; - - tosend = hook_run(p, smps, available, HOOK_WRITE); - if (tosend == 0) - continue; - - sent = node_write(n, smps, tosend); - if (sent < 0) - error("Failed to sent %u samples to node %s", cnt, node_name(n)); - else if (sent < tosend) - warn("Partial write to node %s", node_name(n)); - - debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(n)); - - released = pool_put_many(&p->pool, (void **) smps, sent); - if (sent != released) - warn("Failed to release %u samples to pool for path %s", sent - released, path_name(p)); - } -} - /** Main thread function per path: receive -> sent messages */ static void * path_run(void *arg) { @@ -91,7 +59,34 @@ static void * path_run(void *arg) debug(DBG_PATH | 3, "Enqueuing %u samples to queue of path %s", enqueue, path_name(p)); - path_write(p); + list_foreach(struct node *n, &p->destinations) { + int cnt = n->vectorize; + int sent, tosend, available, released; + struct sample *smps[n->vectorize]; + + available = queue_pull_many(&p->queue, (void **) smps, cnt); + if (available < cnt) + warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); + + if (available == 0) + continue; + + tosend = hook_run(p, smps, available, HOOK_WRITE); + if (tosend == 0) + continue; + + sent = node_write(n, smps, tosend); + if (sent < 0) + error("Failed to sent %u samples to node %s", cnt, node_name(n)); + else if (sent < tosend) + warn("Partial write to node %s", node_name(n)); + + debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(n)); + + released = pool_put_many(&p->pool, (void **) smps, sent); + if (sent != released) + warn("Failed to release %u samples to pool for path %s", sent - released, path_name(p)); + } } return NULL; From 982cd91d638ece928c90539519ae938311f0bf90 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 21:16:01 -0400 Subject: [PATCH 014/211] simplified path_init / prepare logic --- include/villas/path.h | 10 ++-------- lib/cfg.c | 4 +++- lib/path.c | 26 +++++++++----------------- src/node.c | 2 +- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index abd1dfbc2..0bcb4cf56 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -77,8 +77,8 @@ struct path /** @} */ }; -/** Create a path by allocating dynamic memory. */ -void path_init(struct path *p); +/** Initialize internal data structures. */ +int path_init(struct path *p); /** Destroy path by freeing dynamically allocated memory. * @@ -86,12 +86,6 @@ void path_init(struct path *p); */ void path_destroy(struct path *p); -/** Initialize pool queue and hooks. - * - * Should be called after path_init() and before path_start(). - */ -int path_prepare(struct path *p); - /** Start a path. * * Start a new pthread for receiving/sending messages over this path. diff --git a/lib/cfg.c b/lib/cfg.c index 84fbfd35f..f8f4b963d 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -154,7 +154,9 @@ int cfg_parse_path(config_setting_t *cfg, /* Allocate memory and intialize path structure */ p = alloc(sizeof(struct path)); - path_init(p); + + list_init(&p->destinations); + list_init(&p->hooks); /* Input node */ if (!config_setting_lookup_string(cfg, "in", &in) && diff --git a/lib/path.c b/lib/path.c index f94feeea3..6399bb6e1 100644 --- a/lib/path.c +++ b/lib/path.c @@ -135,28 +135,20 @@ const char * path_name(struct path *p) return p->_name; } -void path_init(struct path *p) -{ - list_init(&p->destinations); - list_init(&p->hooks); - - /* Initialize hook system */ - list_foreach(struct hook *h, &hooks) { - if (h->type & HOOK_INTERNAL) - list_push(&p->hooks, memdup(h, sizeof(*h))); - } - - p->state = PATH_CREATED; -} - -int path_prepare(struct path *p) +int path_init(struct path *p) { int ret; - + + /* Add internal hooks if they are not already in the list*/ + list_foreach(struct hook *h, &hooks) { + if ((h->type & HOOK_INTERNAL) && (list_lookup(&p->hooks, h->name) == NULL)) + list_push(&p->hooks, memdup(h, sizeof(struct hook))); + } + /* We sort the hooks according to their priority before starting the path */ list_sort(&p->hooks, hooks_sort_priority); - /* Allocate hook private memory */ + /* Allocate hook private memory for storing state / parameters */ ret = hook_run(p, NULL, 0, HOOK_INIT); if (ret) error("Failed to initialize hooks of path: %s", path_name(p)); diff --git a/src/node.c b/src/node.c index b4cf53cd7..1a4305b90 100644 --- a/src/node.c +++ b/src/node.c @@ -150,7 +150,7 @@ int main(int argc, char *argv[]) info("Starting paths"); list_foreach(struct path *p, &paths) { INDENT if (p->enabled) { - path_prepare(p); + path_init(p); path_start(p); } else From d4e6204e8e6d279690746bde95f08c0fcb042476 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Oct 2016 21:16:47 -0400 Subject: [PATCH 015/211] fixed for rate --- lib/hooks/hooks-stats.c | 10 ++++------ lib/path.c | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index 0d1ce43af..ff5fbd268 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -18,13 +18,12 @@ void hook_stats_header() { #define UNIT(u) "(" YEL(u) ")" - stats("%-40s|%19s|%19s|%19s|%19s|%19s|%10s|", "Source " MAG("=>") " Destination", + stats("%-40s|%19s|%19s|%19s|%19s|%19s|", "Source " MAG("=>") " Destination", "OWD" UNIT("S") " ", "Rate" UNIT("p/S") " ", "Drop" UNIT("p") " ", "Skip" UNIT("p") " ", - "Inval" UNIT("p") " ", - "Overuns " + "Inval" UNIT("p") " " ); line(); } @@ -83,8 +82,8 @@ int hook_stats(struct path *p, struct hook *h, int when, struct sample *smps[], break; case HOOK_PERIODIC: - stats("%-40.40s|%10s|%10s|%10ju|%10ju|%10ju|%10ju|", path_name(p), "", "", - p->dropped, p->skipped, p->invalid, p->overrun); + stats("%-40.40s|%10s|%10s|%10ju|%10ju|%10ju|", path_name(p), "", "", + p->dropped, p->skipped, p->invalid); break; } @@ -124,7 +123,6 @@ int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smp smp->data[i++].f = p->invalid; smp->data[i++].f = p->skipped; smp->data[i++].f = p->dropped; - smp->data[i++].f = p->overrun; smp->data[i++].f = p->hist.owd.last, smp->data[i++].f = 1.0 / p->hist.gap_msg.last; smp->data[i++].f = 1.0 / p->hist.gap_recv.last; diff --git a/lib/path.c b/lib/path.c index 6399bb6e1..7d22f768e 100644 --- a/lib/path.c +++ b/lib/path.c @@ -112,8 +112,8 @@ int path_stop(struct path *p) { info("Stopping path: %s", path_name(p)); - pthread_cancel(p->recv_tid); - pthread_join(p->recv_tid, NULL); + pthread_cancel(p->tid); + pthread_join(p->tid, NULL); if (hook_run(p, NULL, 0, HOOK_PATH_STOP)) return -1; From 1ca719ac6f1f7af41bb87ce51147dbd77dd6cc1e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 12:11:34 -0400 Subject: [PATCH 016/211] use a better name for the new field and added a comment explaining its pupose --- include/villas/webmsg_format.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/villas/webmsg_format.h b/include/villas/webmsg_format.h index 3873d4470..55f885980 100644 --- a/include/villas/webmsg_format.h +++ b/include/villas/webmsg_format.h @@ -80,7 +80,8 @@ struct webmsg unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #endif - uint8_t src_node; /**< Reserved bits */ + uint8_t node_id; /**< The node index from / to which this sample received / sent to. + * Corresponds to the index of the node in the http://localhost/nodes.json array. */ uint16_t length; /**< The number of values in msg::data[]. Endianess is specified in msg::endian. */ uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. Endianess is specified in msg::endian. */ From 9813d2a6c258e94f04a1c7bf58be0fc26d8725bb Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:37:02 -0400 Subject: [PATCH 017/211] use hard coded names for usage info --- src/fpga.c | 10 +++++----- src/node.c | 6 +++--- src/pipe.c | 12 ++++++------ src/signal.c | 8 ++++---- src/test.c | 8 ++++---- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/fpga.c b/src/fpga.c index 46895c0f6..da8205076 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -31,9 +31,9 @@ int fpga_tests(int argc, char *argv[], struct fpga *f); struct settings settings; -void usage(char *name) +void usage() { - printf("Usage: %s CONFIGFILE CMD [OPTIONS]\n", name); + printf("Usage: villas-fpga CONFIGFILE CMD [OPTIONS]\n"); printf(" Commands:\n"); printf(" tests Test functionality of VILLASfpga card\n"); printf(" benchmarks Do benchmarks\n\n"); @@ -57,13 +57,13 @@ int main(int argc, char *argv[]) } subcommand; if (argc < 3) - usage(argv[0]); + usage(); if (strcmp(argv[2], "tests") == 0) subcommand = FPGA_TESTS; else if (strcmp(argv[2], "benchmarks") == 0) subcommand = FPGA_BENCH; else - usage(argv[0]); + usage(); /* Parse arguments */ char c, *endptr; @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) case '?': default: - usage(argv[0]); + usage(); } } diff --git a/src/node.c b/src/node.c index 1a4305b90..4f89f6bbf 100644 --- a/src/node.c +++ b/src/node.c @@ -71,9 +71,9 @@ static void signals_init() sigaction(SIGTERM, &sa_quit, NULL); } -static void usage(const char *name) +static void usage() { - printf("Usage: %s CONFIG\n", name); + printf("Usage: villas-node CONFIG\n"); printf(" CONFIG is a required path to a configuration file\n\n"); #ifdef ENABLE_OPAL_ASYNC printf("Usage: %s OPAL_ASYNC_SHMEM_NAME OPAL_ASYNC_SHMEM_SIZE OPAL_PRINT_SHMEM_NAME\n", name); @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) #else if (argc != 2) #endif - usage(argv[0]); + usage(); char *configfile = (argc == 2) ? argv[1] : "opal-shmem.conf"; diff --git a/src/pipe.c b/src/pipe.c index 334fa0302..626536b08 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -69,9 +69,9 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) exit(EXIT_SUCCESS); } -static void usage(char *name) +static void usage() { - printf("Usage: %s CONFIG NODE [OPTIONS]\n", name); + printf("Usage: villas-pipe CONFIG NODE [OPTIONS]\n"); printf(" CONFIG path to a configuration file\n"); printf(" NODE the name of the node to which samples are sent and received from\n"); printf(" OPTIONS are:\n"); @@ -100,7 +100,7 @@ static void * send_loop(void *ctx) if (ret < 0) error("Failed to allocate memory for receive pool."); - ret = sample_get_many(&sendd.pool, smps, node->vectorize); + ret = sample_alloc(&sendd.pool, smps, node->vectorize); if (ret < 0) error("Failed to get %u samples out of send pool (%d).", node->vectorize, ret); @@ -144,7 +144,7 @@ static void * recv_loop(void *ctx) if (ret < 0) error("Failed to allocate memory for receive pool."); - ret = sample_get_many(&recvv.pool, smps, node->vectorize); + ret = sample_alloc(&recvv.pool, smps, node->vectorize); if (ret < 0) error("Failed to get %u samples out of receive pool (%d).", node->vectorize, ret); @@ -180,7 +180,7 @@ int main(int argc, char *argv[]) /* Parse command line arguments */ if (argc < 3) - usage(argv[0]); + usage(); /* Default values */ sendd.enabled = true; @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) break; case 'h': case '?': - usage(argv[0]); + usage(); } } diff --git a/src/signal.c b/src/signal.c index 82e6b9e27..bce67fadd 100644 --- a/src/signal.c +++ b/src/signal.c @@ -30,9 +30,9 @@ enum SIGNAL_TYPE { TYPE_MIXED }; -void usage(char *name) +void usage() { - printf("Usage: %s SIGNAL [OPTIONS]\n", name); + printf("Usage: villas-signal SIGNAL [OPTIONS]\n"); printf(" SIGNAL is on of: 'mixed', 'random', 'sine', 'triangle', 'square', 'ramp'\n"); printf(" -v NUM specifies how many values a message should contain\n"); printf(" -r HZ how many messages per second\n"); @@ -59,7 +59,7 @@ int main(int argc, char *argv[]) log_init(); if (argc < 2) { - usage(argv[0]); + usage(); exit(EXIT_FAILURE); } @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) goto check; case 'h': case '?': - usage(argv[0]); + usage(); } continue; diff --git a/src/test.c b/src/test.c index ef95b2c65..4f9e351b9 100644 --- a/src/test.c +++ b/src/test.c @@ -53,9 +53,9 @@ void quit() running = 0; } -void usage(char *name) +void usage() { - printf("Usage: %s CONFIG TEST NODE [ARGS]\n", name); + printf("Usage: villas-test CONFIG TEST NODE [ARGS]\n"); printf(" CONFIG path to a configuration file\n"); printf(" TEST the name of the test to execute: 'rtt'\n"); printf(" NODE name of the node which shoud be used\n\n"); @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) config_t config; if (argc < 4) { - usage(argv[0]); + usage(); exit(EXIT_FAILURE); } @@ -184,7 +184,7 @@ void test_rtt() { struct stat st; if (!fstat(fd, &st)) { FILE *f = fdopen(fd, "w"); - hist_matlab(&hist, f); + hist_dump_matlab(&hist, f); } else error("Invalid file descriptor: %u", fd); From d2347102f83dde75b02c5f55424ce371edb72549 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:37:29 -0400 Subject: [PATCH 018/211] fix path to hotdogs --- etc/global.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/global.conf b/etc/global.conf index 163eddb0d..17d51c86f 100644 --- a/etc/global.conf +++ b/etc/global.conf @@ -34,6 +34,6 @@ name = "villas-acs" # The name of this VILLASnode. Might by used by node-typ # to identify themselves (default is the hostname). http = { - htdocs = "/villas/contrib/websocket", # Root directory of internal webserver + htdocs = "/villas/web/socket/", # Root directory of internal webserver port = 80 # Port for HTTP connections } \ No newline at end of file From bee825ae305be8e740901c3a2f2d484e84e9eaf1 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:38:31 -0400 Subject: [PATCH 019/211] generate json object from histogram --- include/villas/hist.h | 12 +++++++++- lib/hist.c | 53 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/include/villas/hist.h b/include/villas/hist.h index 72b232a21..11be82119 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -14,6 +14,10 @@ #include "config.h" +#ifdef WITH_JANSSON + #include +#endif + #define HIST_HEIGHT (LOG_WIDTH - 55) #define HIST_SEQ 17 @@ -75,6 +79,12 @@ void hist_plot(struct hist *h); char * hist_dump(struct hist *h); /** Prints Matlab struct containing all infos to file. */ -void hist_matlab(struct hist *h, FILE *f); +int hist_dump_matlab(struct hist *h, FILE *f); + +#ifdef WITH_JANSSON +int hist_dump_json(struct hist *h, FILE *f); + +json_t * hist_json(struct hist *h); +#endif #endif /* _HIST_H_ */ diff --git a/lib/hist.c b/lib/hist.c index 8f29f6597..33bbce263 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -157,19 +157,60 @@ char * hist_dump(struct hist *h) return buf; } -void hist_matlab(struct hist *h, FILE *f) +#ifdef WITH_JANSSON +json_t * hist_json(struct hist *h) +{ + json_t *b = json_array(); + + for (int i = 0; i < h->length; i++) + json_array_append(b, json_integer(h->data[i])); + + return json_pack("{ s: f, s: f, s: i, s: i, s: i, s: f, s: f, s: f, s: f, s: f, s: o }", + "low", h->low, + "high", h->high, + "total", h->total, + "higher", h->higher, + "lower", h->lower, + "highest", h->highest, + "lowest", h->lowest, + "mean", hist_mean(h), + "variance", hist_var(h), + "stddev", hist_stddev(h), + "buckets", b + ); +} + +int hist_dump_json(struct hist *h, FILE *f) +{ + json_t *j = hist_json(h); + + int ret = json_dumpf(j, f, 0); + + json_decref(j); + + return ret; +} +#endif /* WITH_JANNSON */ + +int hist_dump_matlab(struct hist *h, FILE *f) { char *buf = hist_dump(h); fprintf(f, "%lu = struct( ", time(NULL)); - fprintf(f, "'min', %f, 'max', %f, ", h->low, h->high); - fprintf(f, "'total', %u, higher', %u, 'lower', %u, ", h->total, h->higher, h->lower); - fprintf(f, "'highest', %f, 'lowest', %f, ", h->highest, h->lowest); + fprintf(f, "'low', %f, ", h->low); + fprintf(f, "'high', %f, ", h->high); + fprintf(f, "'total', %u, ", h->total); + fprintf(f, "'higher', %u, ", h->higher); + fprintf(f, "'lower', %u, ", h->lower); + fprintf(f, "'highest', %f, ", h->highest); + fprintf(f, "'lowest', %f, ", h->lowest); fprintf(f, "'mean', %f, ", hist_mean(h)); - fprintf(f, "'var', %f, ", hist_var(h)); + fprintf(f, "'variance', %f, ", hist_var(h)); fprintf(f, "'stddev', %f, ", hist_stddev(h)); - fprintf(f, "'hist', %s ", buf); + fprintf(f, "'buckets', %s ", buf); fprintf(f, "),\n"); free(buf); + + return 0; } From a9363dad44df9f2277217ba1898ea5baf68c4e35 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:42:05 -0400 Subject: [PATCH 020/211] entangle hook and statistic collection system --- include/villas/hooks.h | 58 +++++++++------ include/villas/stats.h | 63 ++++++++++++++++ lib/Makefile.inc | 2 +- lib/hooks.c | 44 +++++++++--- lib/hooks/hooks-internal.c | 63 ++++++++-------- lib/hooks/hooks-other.c | 78 +++++++++++--------- lib/hooks/hooks-stats.c | 95 ++++++------------------- lib/stats.c | 142 +++++++++++++++++++++++++++++++++++++ 8 files changed, 376 insertions(+), 169 deletions(-) create mode 100644 include/villas/stats.h create mode 100644 lib/stats.c diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 9eae7bb6b..7c69b0125 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -50,17 +50,33 @@ struct settings; /** This is a list of hooks which can be used in the configuration file. */ extern struct list hooks; +/** Optional parameters to hook callbacks */ +struct hook_info { + struct node *node; + struct path *path; + + struct sample **smps; + size_t cnt; + + struct list *paths; + struct list *nodes; + struct settings *settings; +}; + /** Callback type of hook function * - * @param p The path which is processing this message. * @param h The hook datastructure which contains parameter, name and private context for the hook. - * @param m A pointer to the first message which should be processed by the hook. - * @param cnt The number of messages which should be processed by the hook. * @param when Provides the type of hook for which this occurence of the callback function was executed. See hook_type for possible values. + * @param i The hook_info structure contains references to the current node, path or samples. Some fields of this structure can be NULL. * @retval 0 Success. Continue processing and forwarding the message. * @retval <0 Error. Drop the message. */ -typedef int (*hook_cb_t)(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); +typedef int (*hook_cb_t)(struct hook *h, int when, struct hook_info *i); + +enum hook_state { + HOOK_DESTROYED, + HOOK_INITIALIZED +}; /** The type of a hook defines when a hook will be exectuted. This is used as a bitmask. */ enum hook_type { @@ -74,15 +90,15 @@ enum hook_type { HOOK_ASYNC = 1 << 7, /**< Called asynchronously with fixed rate (see path::rate). */ HOOK_PERIODIC = 1 << 8, /**< Called periodically. Period is set by global 'stats' option in the configuration file. */ - HOOK_INIT = 1 << 9, /**< Called before path is started to parse parameters. */ - HOOK_DEINIT = 1 << 10, /**< Called after path has been stopped to release memory allocated by HOOK_INIT */ + HOOK_INIT = 1 << 9, /**< Called before path is started to parseHOOK_DESTROYs. */ + HOOK_DESTROY = 1 << 10, /**< Called after path has been stopped to release memory allocated by HOOK_INIT */ HOOK_INTERNAL = 1 << 11, /**< Internal hooks are added to every path implicitely. */ HOOK_PARSE = 1 << 12, /**< Called for parsing hook arguments. */ /** @{ Classes of hooks */ /** Hooks which are using private data must allocate and free them propery. */ - HOOK_STORAGE = HOOK_INIT | HOOK_DEINIT, + HOOK_STORAGE = HOOK_INIT | HOOK_DESTROY, /** All path related actions */ HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART, /** Hooks which are used to collect statistics. */ @@ -111,8 +127,11 @@ struct hook { hook_cb_t cb; /**< The hook callback function as a function pointer. */ }; -/** Save references to global nodes, paths and settings */ -void hook_init(struct list *nodes, struct list *paths, struct settings *set); +int hook_init(struct hook *h, struct list *nodes, struct list *paths, struct settings *settings); + +void hook_destroy(struct hook *h); + +int hook_copy(struct hook *h, struct hook *c); /** Sort hook list according to the their priority. See hook::priority. */ int hooks_sort_priority(const void *a, const void *b); @@ -139,18 +158,17 @@ int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when); */ void * hook_storage(struct hook *h, int when, size_t len); -int hook_print(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_ts(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_convert(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_decimate(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_skip_first(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); +int hook_print(struct hook *h, int when, struct hook_info *j); +int hook_ts(struct hook *h, int when, struct hook_info *j); +int hook_convert(struct hook *h, int when, struct hook_info *j); +int hook_decimate(struct hook *h, int when, struct hook_info *j); +int hook_skip_first(struct hook *h, int when, struct hook_info *j); -int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_stats(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -void hook_stats_header(); +int hook_stats_send(struct hook *h, int when, struct hook_info *j); +int hook_stats(struct hook *h, int when, struct hook_info *j); -int hook_fix_ts(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_restart(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_drop(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); +int hook_fix_ts(struct hook *h, int when, struct hook_info *j); +int hook_restart(struct hook *h, int when, struct hook_info *j); +int hook_drop(struct hook *h, int when, struct hook_info *j); #endif /** _HOOKS_H_ @} */ diff --git a/include/villas/stats.h b/include/villas/stats.h new file mode 100644 index 000000000..e6260833b --- /dev/null +++ b/include/villas/stats.h @@ -0,0 +1,63 @@ +/** Statistic collection. + * + * @file + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ + +#ifndef _STATS_H_ +#define _STATS_H_ + +#include + +#ifdef WITH_JANSSON + #include +#endif + +#include "hist.h" + +/* Forward declarations */ +struct sample; +struct path; +struct node; + +struct stats { + struct { + uintmax_t invalid; /**< Counter for invalid messages */ + uintmax_t skipped; /**< Counter for skipped messages due to hooks */ + uintmax_t dropped; /**< Counter for dropped messages due to reordering */ + } counter; + + struct { + struct hist owd; /**< Histogram for one-way-delay (OWD) of received messages */ + struct hist gap_msg; /**< Histogram for inter message timestamps (as sent by remote) */ + struct hist gap_recv; /**< Histogram for inter message arrival time (as seen by this instance) */ + struct hist gap_seq; /**< Histogram of sequence number displacement of received messages */ + } histogram; + + struct sample *last; +}; + +int stats_init(struct stats *s); + +void stats_destroy(struct stats *s); + +void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); + +#ifdef WITH_JANSSON +json_t * stats_json(struct stats *s); +#endif + +void stats_reset(struct stats *s); + +void stats_print_header(); + +void stats_print_periodic(struct stats *s, struct path *p); + +void stats_print(struct stats *s); + +void stats_send(struct stats *s, struct node *n); + +#endif /* _STATS_H_ */ \ No newline at end of file diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 21b221772..258c50d14 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -6,7 +6,7 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ $(addprefix lib/, sample.c path.c node.c hooks.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ - queue.c memory.c \ + queue.c memory.c stats.c \ ) \ $(wildcard lib/hooks/*.c) \ diff --git a/lib/hooks.c b/lib/hooks.c index ea4745e80..5ffcc9044 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -19,16 +19,32 @@ struct list hooks; -/* Those references can be used inside the hook callbacks after initializing them with hook_init() */ -struct list *hook_nodes = NULL; -struct list *hook_paths = NULL; -struct settings *hook_settings = NULL; - -void hook_init(struct list *nodes, struct list *paths, struct settings *set) +int hook_init(struct hook *h, struct list *nodes, struct list *paths, struct settings *settings) { - hook_nodes = nodes; - hook_paths = paths; - hook_settings = set; + struct hook_info i = { + .paths = paths, + .nodes = nodes, + .settings = settings + }; + + return h->cb(h, HOOK_INIT, &i); +} + +void hook_destroy(struct hook *h) +{ + struct hook_info i = { NULL }; + h->cb(h, HOOK_DESTROY, &i); +} + +int hook_copy(struct hook *h, struct hook *c) +{ + memcpy(c, h, sizeof(struct hook)); + + c->_vd = + c->prev = + c->last = NULL; + + return 0; } int hooks_sort_priority(const void *a, const void *b) { @@ -40,11 +56,17 @@ int hooks_sort_priority(const void *a, const void *b) { int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when) { + struct hook_info i = { + .path = p, + .smps = smps, + .cnt = cnt + }; + list_foreach(struct hook *h, &p->hooks) { if (h->type & when) { debug(DBG_HOOK | 22, "Running hook when=%u '%s' prio=%u, cnt=%zu", when, h->name, h->priority, cnt); - cnt = h->cb(p, h, when, smps, cnt); + cnt = h->cb(h, when, &i); if (cnt == 0) break; } @@ -60,7 +82,7 @@ void * hook_storage(struct hook *h, int when, size_t len) h->_vd = alloc(len); break; - case HOOK_DEINIT: + case HOOK_DESTROY: free(h->_vd); h->_vd = NULL; break; diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 26958703c..070e68359 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -13,75 +13,78 @@ #include "utils.h" REGISTER_HOOK("fix_ts", "Update timestamps of sample if not set", 0, 0, hook_fix_ts, HOOK_INTERNAL | HOOK_READ) -int hook_fix_ts(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_fix_ts(struct hook *h, int when, struct hook_info *j) { struct timespec now = time_now(); + + assert(j->smps); - for (int i = 0; i < cnt; i++) { + for (int i = 0; i < j->cnt; i++) { /* Check for missing receive timestamp * Usually node_type::read() should update the receive timestamp. * An example would be to use hardware timestamp capabilities of * modern NICs. */ - if ((smps[i]->ts.received.tv_sec == 0 && smps[i]->ts.received.tv_nsec == 0) || - (smps[i]->ts.received.tv_sec == -1 && smps[i]->ts.received.tv_nsec == -1)) - smps[i]->ts.received = now; + if ((j->smps[i]->ts.received.tv_sec == 0 && j->smps[i]->ts.received.tv_nsec == 0) || + (j->smps[i]->ts.received.tv_sec == -1 && j->smps[i]->ts.received.tv_nsec == -1)) + j->smps[i]->ts.received = now; /* Check for missing origin timestamp */ - if ((smps[i]->ts.origin.tv_sec == 0 && smps[i]->ts.origin.tv_nsec == 0) || - (smps[i]->ts.origin.tv_sec == -1 && smps[i]->ts.origin.tv_nsec == -1)) - smps[i]->ts.origin = now; + if ((j->smps[i]->ts.origin.tv_sec == 0 && j->smps[i]->ts.origin.tv_nsec == 0) || + (j->smps[i]->ts.origin.tv_sec == -1 && j->smps[i]->ts.origin.tv_nsec == -1)) + j->smps[i]->ts.origin = now; } - return cnt; + return j->cnt; } REGISTER_HOOK("restart", "Call restart hooks for current path", 1, 1, hook_restart, HOOK_INTERNAL | HOOK_READ) -int hook_restart(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_restart(struct hook *h, int when, struct hook_info *j) { - for (int i = 0; i < cnt; i++) { - h->last = smps[i]; + assert(j->smps); + assert(j->path); + + for (int i = 0; i < j->cnt; i++) { + h->last = j->smps[i]; if (h->prev) { if (h->last->sequence == 0 && h->prev->sequence <= UINT32_MAX - 32) { warn("Simulation for path %s restarted (prev->seq=%u, current->seq=%u)", - path_name(p), h->prev->sequence, h->last->sequence); + path_name(j->path), h->prev->sequence, h->last->sequence); - p->invalid = - p->skipped = - p->dropped = 0; - - hook_run(p, &smps[i], cnt - i, HOOK_PATH_RESTART); + hook_run(j->path, &j->smps[i], j->cnt - i, HOOK_PATH_RESTART); } } h->prev = h->last; } - return cnt; + return j->cnt; } REGISTER_HOOK("drop", "Drop messages with reordered sequence numbers", 3, 1, hook_drop, HOOK_INTERNAL | HOOK_READ) -int hook_drop(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_drop(struct hook *h, int when, struct hook_info *j) { int i, ok, dist; + + assert(j->smps); - for (i = 0, ok = 0; i < cnt; i++) { - h->last = smps[i]; + for (i = 0, ok = 0; i < j->cnt; i++) { + h->last = j->smps[i]; if (h->prev) { dist = h->last->sequence - (int32_t) h->prev->sequence; if (dist <= 0) { - p->dropped++; + j->path->stats->counter.dropped++; warn("Dropped sample: dist = %d, i = %d", dist, i); } else { struct sample *tmp; - tmp = smps[i]; - smps[i] = smps[ok]; - smps[ok++] = tmp; + tmp = j->smps[i]; + j->smps[i] = j->smps[ok]; + j->smps[ok++] = tmp; } /* To discard the first X samples in 'smps[]' we must @@ -93,11 +96,11 @@ int hook_drop(struct path *p, struct hook *h, int when, struct sample *smps[], s else { struct sample *tmp; - tmp = smps[i]; - smps[i] = smps[ok]; - smps[ok++] = tmp; + tmp = j->smps[i]; + j->smps[i] = j->smps[ok]; + j->smps[ok++] = tmp; } - + h->prev = h->last; } diff --git a/lib/hooks/hooks-other.c b/lib/hooks/hooks-other.c index 21814ef29..86733cb19 100644 --- a/lib/hooks/hooks-other.c +++ b/lib/hooks/hooks-other.c @@ -17,25 +17,29 @@ #include "sample.h" REGISTER_HOOK("print", "Print the message to stdout", 99, 0, hook_print, HOOK_READ) -int hook_print(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_print(struct hook *h, int when, struct hook_info *j) { - for (int i = 0; i < cnt; i++) - sample_fprint(stdout, smps[i], SAMPLE_ALL); + assert(j->smps); + + for (int i = 0; i < j->cnt; i++) + sample_fprint(stdout, j->smps[i], SAMPLE_ALL); - return cnt; + return j->cnt; } REGISTER_HOOK("ts", "Update timestamp of message with current time", 99, 0, hook_ts, HOOK_READ) -int hook_ts(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_ts(struct hook *h, int when, struct hook_info *j) { - for (int i = 0; i < cnt; i++) - smps[i]->ts.origin = smps[i]->ts.received; + assert(j->smps); - return cnt; + for (int i = 0; i < j->cnt; i++) + j->smps[i]->ts.origin = j->smps[i]->ts.received; + + return j->cnt; } -REGISTER_HOOK("convert", "Convert message from / to floating-point / integer", 99, 0, hook_convert, HOOK_STORAGE | HOOK_PARSE | HOOK_READ) -int hook_convert(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +REGISTER_HOOK("convert", "Convert message from / to floating-point / integer", 99, 0, hook_convert, HOOK_STORAGE | HOOK_DESTROY | HOOK_READ) +int hook_convert(struct hook *h, int when, struct hook_info *k) { struct { enum { @@ -45,7 +49,7 @@ int hook_convert(struct path *p, struct hook *h, int when, struct sample *smps[] } *private = hook_storage(h, when, sizeof(*private)); switch (when) { - case HOOK_PARSE: + case HOOK_DESTROY: if (!h->parameter) error("Missing parameter for hook: '%s'", h->name); @@ -58,30 +62,29 @@ int hook_convert(struct path *p, struct hook *h, int when, struct sample *smps[] break; case HOOK_READ: - for (int i = 0; i < cnt; i++) { - for (int j = 0; j < smps[0]->length; j++) { + for (int i = 0; i < k->cnt; i++) { + for (int j = 0; j < k->smps[0]->length; j++) { switch (private->mode) { - case TO_FIXED: smps[i]->data[j].i = smps[i]->data[j].f * 1e3; break; - case TO_FLOAT: smps[i]->data[j].f = smps[i]->data[j].i; break; + case TO_FIXED: k->smps[i]->data[j].i = k->smps[i]->data[j].f * 1e3; break; + case TO_FLOAT: k->smps[i]->data[j].f = k->smps[i]->data[j].i; break; } } } - break; + + return k->cnt; } return 0; } -REGISTER_HOOK("decimate", "Downsamping by integer factor", 99, 0, hook_decimate, HOOK_STORAGE | HOOK_PARSE | HOOK_READ) -int hook_decimate(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +REGISTER_HOOK("decimate", "Downsamping by integer factor", 99, 0, hook_decimate, HOOK_STORAGE | HOOK_DESTROY | HOOK_READ) +int hook_decimate(struct hook *h, int when, struct hook_info *j) { struct { unsigned ratio; unsigned counter; } *private = hook_storage(h, when, sizeof(*private)); - int ok; - switch (when) { case HOOK_PARSE: if (!h->parameter) @@ -95,24 +98,27 @@ int hook_decimate(struct path *p, struct hook *h, int when, struct sample *smps[ break; case HOOK_READ: - ok = 0; - for (int i = 0; i < cnt; i++) { + assert(j->smps); + + int i, ok; + for (i = 0, ok = 0; i < j->cnt; i++) { if (private->counter++ % private->ratio == 0) { struct sample *tmp; - tmp = smps[ok]; - smps[ok++] = smps[i]; - smps[i] = tmp; + tmp = j->smps[ok]; + j->smps[ok++] = j->smps[i]; + j->smps[i] = tmp; } } + return ok; } - return cnt; + return 0; } REGISTER_HOOK("skip_first", "Skip the first samples", 99, 0, hook_skip_first, HOOK_STORAGE | HOOK_PARSE | HOOK_READ | HOOK_PATH) -int hook_skip_first(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_skip_first(struct hook *h, int when, struct hook_info *j) { struct { struct timespec skip; /**< Time to wait until first message is not skipped */ @@ -121,7 +127,6 @@ int hook_skip_first(struct path *p, struct hook *h, int when, struct sample *smp char *endptr; double wait; - int i, ok; switch (when) { case HOOK_PARSE: @@ -135,19 +140,22 @@ int hook_skip_first(struct path *p, struct hook *h, int when, struct sample *smp private->skip = time_from_double(wait); break; + case HOOK_PATH_START: case HOOK_PATH_RESTART: - case HOOK_PATH_STOP: - private->until = time_add(&smps[0]->ts.received, &private->skip); + private->until = time_add(&j->smps[0]->ts.received, &private->skip); break; case HOOK_READ: - for (i = 0, ok = 0; i < cnt; i++) { - if (time_delta(&private->until, &smps[i]->ts.received) > 0) { + assert(j->smps); + + int i, ok; + for (i = 0, ok = 0; i < j->cnt; i++) { + if (time_delta(&private->until, &j->smps[i]->ts.received) > 0) { struct sample *tmp; - tmp = smps[i]; - smps[i] = smps[ok]; - smps[ok++] = tmp; + tmp = j->smps[i]; + j->smps[i] = j->smps[ok]; + j->smps[ok++] = tmp; } diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index ff5fbd268..4b787b78f 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -10,88 +10,51 @@ #include "sample.h" #include "path.h" #include "utils.h" -#include "timing.h" +#include "stats.h" extern struct list *hook_nodes; -void hook_stats_header() -{ - #define UNIT(u) "(" YEL(u) ")" - - stats("%-40s|%19s|%19s|%19s|%19s|%19s|", "Source " MAG("=>") " Destination", - "OWD" UNIT("S") " ", - "Rate" UNIT("p/S") " ", - "Drop" UNIT("p") " ", - "Skip" UNIT("p") " ", - "Inval" UNIT("p") " " - ); - line(); -} - REGISTER_HOOK("stats", "Collect statistics for the current path", 2, 1, hook_stats, HOOK_STATS) -int hook_stats(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +int hook_stats(struct hook *h, int when, struct hook_info *j) { + struct stats *s = hook_storage(h, when, sizeof(struct stats)); + switch (when) { case HOOK_INIT: - /** @todo Allow configurable bounds for histograms */ - hist_create(&p->hist.owd, 0, 1, 100e-3); - hist_create(&p->hist.gap_msg, 90e-3, 110e-3, 1e-3); - hist_create(&p->hist.gap_recv, 90e-3, 110e-3, 1e-3); - hist_create(&p->hist.gap_seq, -HIST_SEQ, +HIST_SEQ, 1); + stats_init(s); break; case HOOK_READ: - for (int i = 0; i < cnt; i++) { - h->last = smps[i]; - - if (h->prev) { - int gap_seq = h->last->sequence - (int32_t) h->prev->sequence; - double owd = time_delta(&h->last->ts.origin, &h->last->ts.received); - double gap = time_delta(&h->prev->ts.origin, &h->last->ts.origin); - double gap_recv = time_delta(&h->prev->ts.received, &h->last->ts.received); - - hist_put(&p->hist.gap_msg, gap); - hist_put(&p->hist.gap_seq, gap_seq); - hist_put(&p->hist.owd, owd); - hist_put(&p->hist.gap_recv, gap_recv); - } - - h->prev = h->last; - } + assert(j->smps); + + stats_collect(s, j->smps, j->cnt); break; case HOOK_PATH_STOP: - if (p->hist.owd.total) { info("One-way delay:"); hist_print(&p->hist.owd); } - if (p->hist.gap_recv.total){ info("Inter-message arrival time:"); hist_print(&p->hist.gap_recv); } - if (p->hist.gap_msg.total) { info("Inter-message ts gap:"); hist_print(&p->hist.gap_msg); } - if (p->hist.gap_seq.total) { info("Inter-message sequence number gaps:"); hist_print(&p->hist.gap_seq); } + stats_print(s); break; - case HOOK_DEINIT: - hist_destroy(&p->hist.owd); - hist_destroy(&p->hist.gap_msg); - hist_destroy(&p->hist.gap_recv); - hist_destroy(&p->hist.gap_seq); + case HOOK_DESTROY: + stats_destroy(s); break; case HOOK_PATH_RESTART: - hist_reset(&p->hist.owd); - hist_reset(&p->hist.gap_seq); - hist_reset(&p->hist.gap_msg); - hist_reset(&p->hist.gap_recv); + stats_reset(s); break; case HOOK_PERIODIC: - stats("%-40.40s|%10s|%10s|%10ju|%10ju|%10ju|", path_name(p), "", "", - p->dropped, p->skipped, p->invalid); + assert(j->path); + + stats_print_periodic(s, j->path); break; } - return cnt; + return j->cnt; } -REGISTER_HOOK("stats_send", "Send path statistics to another node", 99, 0, hook_stats_send, HOOK_STORAGE | HOOK_PARSE | HOOK_PERIODIC | HOOK_PATH) -int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +#if 0 /* currently broken */ +REGISTER_HOOK("stats_send", "Send path statistics to another node", 99, 0, hook_stats_send, HOOK_STORAGE | HOOK_DESTROY | HOOK_PERIODIC | HOOK_PATH) +int hook_stats_send(struct hook *h, int when, struct hook_info *i) { struct private { struct node *dest; @@ -99,7 +62,7 @@ int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smp } *private = hook_storage(h, when, sizeof(*private)); switch (when) { - case HOOK_PARSE: + case HOOK_DESTROY: if (!h->parameter) error("Missing parameter for hook '%s'", h->name); @@ -115,23 +78,11 @@ int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smp break; case HOOK_PERIODIC: { - int i; - char buf[SAMPLE_LEN(16)]; - struct sample *smp = (struct sample *) buf; - - i = 0; - smp->data[i++].f = p->invalid; - smp->data[i++].f = p->skipped; - smp->data[i++].f = p->dropped; - smp->data[i++].f = p->hist.owd.last, - smp->data[i++].f = 1.0 / p->hist.gap_msg.last; - smp->data[i++].f = 1.0 / p->hist.gap_recv.last; - smp->length = i; - - node_write(private->dest, &smp, 1); /* Send single message with statistics to destination node */ + stats_send(s, node); break; } } return 0; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/lib/stats.c b/lib/stats.c new file mode 100644 index 000000000..f25675d1d --- /dev/null +++ b/lib/stats.c @@ -0,0 +1,142 @@ +/** Statistic collection. + * + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ + +#include "stats.h" +#include "hist.h" +#include "timing.h" +#include "path.h" +#include "sample.h" +#include "log.h" + +int stats_init(struct stats *s) +{ + /** @todo Allow configurable bounds for histograms */ + hist_create(&s->histogram.owd, 0, 1, 100e-3); + hist_create(&s->histogram.gap_msg, 90e-3, 110e-3, 1e-3); + hist_create(&s->histogram.gap_recv, 90e-3, 110e-3, 1e-3); + hist_create(&s->histogram.gap_seq, -HIST_SEQ, +HIST_SEQ, 1); + + return 0; +} + +void stats_destroy(struct stats *s) +{ + hist_destroy(&s->histogram.owd); + hist_destroy(&s->histogram.gap_msg); + hist_destroy(&s->histogram.gap_recv); + hist_destroy(&s->histogram.gap_seq); +} + +void stats_collect(struct stats *s, struct sample *smps[], size_t cnt) +{ + for (int i = 0; i < cnt; i++) { + if (s->last) { + int gap_seq = smps[i]->sequence - (int32_t) s->last->sequence; + double owd = time_delta(&smps[i]->ts.origin, &smps[i]->ts.received); + double gap = time_delta(&s->last->ts.origin, &smps[i]->ts.origin); + double gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received); + + hist_put(&s->histogram.owd, owd); + hist_put(&s->histogram.gap_msg, gap); + hist_put(&s->histogram.gap_seq, gap_seq); + hist_put(&s->histogram.gap_recv, gap_recv); + } + + if (i == 0 && s->last) + sample_put(s->last); + if (i == cnt - 1) + sample_get(smps[i]); + + s->last = smps[i]; + } +} + +#ifdef WITH_JANSSON +json_t * stats_json(struct stats *s) +{ + return json_pack("{ s: { s: i, s: i, s: i }, s: { s: o, s: o, s: o } }", + "counter", + "dropped", s->counter.dropped, + "invalid", s->counter.invalid, + "skipped", s->counter.skipped, + "histogram", + "owd", hist_json(&s->histogram.owd), + "gap_msg", hist_json(&s->histogram.gap_msg), + "gap_recv",hist_json(&s->histogram.gap_recv), + "gap_seq", hist_json(&s->histogram.gap_seq) + ); +} +#endif + +void stats_reset(struct stats *s) +{ + s->counter.invalid = + s->counter.skipped = + s->counter.dropped = 0; + + hist_reset(&s->histogram.owd); + hist_reset(&s->histogram.gap_seq); + hist_reset(&s->histogram.gap_msg); + hist_reset(&s->histogram.gap_recv); +} + +void stats_print_header() +{ + #define UNIT(u) "(" YEL(u) ")" + + stats("%-40s|%19s|%19s|%19s|%19s|%19s|", "Source " MAG("=>") " Destination", + "OWD" UNIT("S") " ", + "Rate" UNIT("p/S") " ", + "Drop" UNIT("p") " ", + "Skip" UNIT("p") " ", + "Inval" UNIT("p") " " + ); + line(); +} + +void stats_print_periodic(struct stats *s, struct path *p) +{ + stats("%-40.40s|%10s|%10s|%10ju|%10ju|%10ju|", path_name(p), "", "", + s->counter.dropped, s->counter.skipped, s->counter.invalid); +} + +void stats_print(struct stats *s) +{ + stats("Dropped samples: %ju", s->counter.dropped); + stats("Skipped samples: %ju", s->counter.skipped); + stats("Invalid samples: %ju", s->counter.invalid); + + stats("One-way delay:"); + hist_print(&s->histogram.owd); + + stats("Inter-message arrival time:"); + hist_print(&s->histogram.gap_recv); + + stats("Inter-message ts gap:"); + hist_print(&s->histogram.gap_msg); + + stats("Inter-message sequence number gaps:"); + hist_print(&s->histogram.gap_seq); +} + +void stats_send(struct stats *s, struct node *n) +{ + char buf[SAMPLE_LEN(16)]; + struct sample *smp = (struct sample *) buf; + + int i = 0; + smp->data[i++].f = s->counter.invalid; /**< Use integer here? */ + smp->data[i++].f = s->counter.skipped; + smp->data[i++].f = s->counter.dropped; + smp->data[i++].f = s->histogram.owd.last, + smp->data[i++].f = 1.0 / s->histogram.gap_msg.last; + smp->data[i++].f = 1.0 / s->histogram.gap_recv.last; + smp->length = i; + + node_write(n, &smp, 1); /* Send single message with statistics to destination node */ +} \ No newline at end of file From 5ba5164c1ac5a2406f21a7e435924483c5bd5ba1 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:43:36 -0400 Subject: [PATCH 021/211] added new tool to run hook functions with villas-pipe and villas-signal --- plugins/hooks/example_hook.c | 2 +- src/Makefile.inc | 3 +- src/hook.c | 121 +++++++++++++++++++++++++++++++++++ src/node.c | 9 +-- 4 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 src/hook.c diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index 843b2734c..22e1b48dc 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -1,7 +1,7 @@ #include #include -static int hook_example(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) +static int hook_example(struct hook *h, int when, struct hook_info *j) { info("Hello world from example hook!"); diff --git a/src/Makefile.inc b/src/Makefile.inc index 280efdbe2..94cd8fcdb 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -2,7 +2,8 @@ TARGETS = $(BUILDDIR)/villas-node \ $(BUILDDIR)/villas-pipe \ $(BUILDDIR)/villas-signal \ - $(BUILDDIR)/villas-test + $(BUILDDIR)/villas-test \ + $(BUILDDIR)/villas-hook SRC_LDLIBS = $(LDLIBS) -pthread -lm -lvillas SRC_CFLAGS = $(CFLAGS) diff --git a/src/hook.c b/src/hook.c new file mode 100644 index 000000000..a68a8bfae --- /dev/null +++ b/src/hook.c @@ -0,0 +1,121 @@ +/** Receive messages from server snd print them on stdout. + * + * @file + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + * + * @addtogroup tools Test and debug tools + * @{ + *********************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void usage() +{ + printf("Usage: villas-hook [OPTIONS] NAME [PARAMETER] \n"); + printf(" NAME the name of the hook function to run\n"); + printf(" PARAM the name of the node to which samples are sent and received from\n\n"); + printf(" OPTIONS are:\n"); + printf(" -h show this help\n"); + printf(" -d lvl set debug level\n"); + printf(" -v process multiple samples at once\n\n"); + + print_copyright(); +} + +int main(int argc, char *argv[]) +{ + int j, ret, cnt = 1; + + char *name, *parameter; + + struct hook *h; + struct hook_info *i = alloc(sizeof(struct hook_info)); + + char c; + while ((c = getopt(argc, argv, "hv:d:")) != -1) { + switch (c) { + case 'v': + cnt = atoi(optarg); + break; + case 'd': + log_setlevel(atoi(optarg), -1); + break; + case 'h': + case '?': + usage(argv[0]); + exit(EXIT_SUCCESS); + } + } + + if (argc <= optind) + + name = argc > optind ? argv[optind ] : NULL; + parameter = argc > optind + 1 ? argv[optind+1] : NULL; + + if (argc > optind) + name = argv[optind]; + else { + usage(argv[0]); + exit(EXIT_FAILURE); + } + + if (argc > optind + 1) + parameter = argv[optind + 1]; + + h = list_lookup(&hooks, name); + if (!h) + error("Unknown hook function '%s'", argv[optind]); + + if (cnt < 1) + error("Vectorize option must be greater than 0"); + + struct pool pool; + struct sample *smps[cnt]; + + ret = pool_init(&pool, 10 * cnt, SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); + if (ret) + error("Failed to initilize memory pool"); + + ret = sample_alloc(&pool, smps, cnt); + if (ret) + error("Failed to allocate %u samples from pool", cnt); + + h->parameter = parameter; + i->smps = smps; + + h->cb(h, HOOK_INIT, i); + h->cb(h, HOOK_PARSE, i); + h->cb(h, HOOK_PATH_START, i); + + while (!feof(stdin)) { + for (j = 0; j < cnt && !feof(stdin); j++) + sample_fscan(stdin, i->smps[j], NULL); + + i->cnt = j; + i->cnt = h->cb(h, HOOK_READ, i); + i->cnt = h->cb(h, HOOK_WRITE, i); + + for (j = 0; j < i->cnt; j++) + sample_fprint(stdout, i->smps[j], SAMPLE_ALL); + } + + h->cb(h, HOOK_PATH_STOP, i); + h->cb(h, HOOK_DESTROY, i); + + sample_free(smps, cnt); + + pool_destroy(&pool); + + return 0; +} \ No newline at end of file diff --git a/src/node.c b/src/node.c index 4f89f6bbf..93c42b1fc 100644 --- a/src/node.c +++ b/src/node.c @@ -128,9 +128,6 @@ int main(int argc, char *argv[]) info("Initialize signals"); signals_init(); - info("Initialize hook sub-system"); - hook_init(&nodes, &paths, &settings); - info("Initialize node types"); list_foreach(struct node_type *vt, &node_types) { INDENT int refs = list_length(&vt->instances); @@ -151,6 +148,10 @@ int main(int argc, char *argv[]) list_foreach(struct path *p, &paths) { INDENT if (p->enabled) { path_init(p); + + list_foreach(struct hook *h, &p->hooks) + hook_init(h, &nodes, &paths, &settings); + path_start(p); } else @@ -159,7 +160,7 @@ int main(int argc, char *argv[]) /* Run! */ if (settings.stats > 0) { - hook_stats_header(); + stats_print_header(); for (;;) { list_foreach(struct path *p, &paths) From f82fc64990d0bceed27271d2b121787e7f857b55 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:43:55 -0400 Subject: [PATCH 022/211] removed two unused functions --- include/villas/utils.h | 6 ------ lib/utils.c | 37 ------------------------------------- 2 files changed, 43 deletions(-) diff --git a/include/villas/utils.h b/include/villas/utils.h index 82b7cabb7..87f2a6c69 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -197,12 +197,6 @@ int version_parse(const char *s, struct version *v); /** Fill buffer with random data */ int read_random(char *buf, size_t len); -/** Hexdump bytes */ -void printb(void *mem, size_t len); - -/** Hexdump 32-bit dwords */ -void printdw(void *mem, size_t len); - /** Get CPU timestep counter */ __attribute__((always_inline)) static inline uint64_t rdtsc() { diff --git a/lib/utils.c b/lib/utils.c index eff72a954..2c7fb04fd 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -329,43 +329,6 @@ out: return -1; } -void printb(void *mem, size_t len) -{ - uint8_t *mem8 = (uint8_t *) mem; - - for (int i = 0; i < len; i++) { - printf("%02hx ", mem8[i]); - - if (i % 16 == 15) - printf("\n"); - } -} - -void printdw(void *mem, size_t len) -{ - int columns = 4; - - uint32_t *mem32 = (uint32_t *) mem; - - for (int i = 0; i < len; i++) { - if (i % columns == 0) - printf("%#x: ", i * 4); - - printf("%08x ", mem32[i]); - - char *memc = (char *) &mem32[i]; - printf("%c%c%c%c ", - isprint(memc[0]) ? memc[0] : ' ', - isprint(memc[1]) ? memc[1] : ' ', - isprint(memc[2]) ? memc[2] : ' ', - isprint(memc[3]) ? memc[3] : ' ' - ); - - if ((i+1) % columns == 0) - printf("\n"); - } -} - void rdtsc_sleep(uint64_t nanosecs, uint64_t start) { uint64_t cycles; From d5c844f18d1dd811877d4837ad306f4839483158 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:44:18 -0400 Subject: [PATCH 023/211] added LOG2_CEIL --- include/villas/utils.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/villas/utils.h b/include/villas/utils.h index 87f2a6c69..4207d3626 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -55,7 +55,11 @@ #define ALIGN_MASK(x, m) (((uintptr_t) (x) + (m)) & ~(m)) #define IS_ALIGNED(x, a) (ALIGN(x, a) == (uintptr_t) x) -#define CEIL(x, y) ((x + y - 1) / y) +/** Round-up integer division */ +#define CEIL(x, y) (((x) + (y) - 1) / (y)) + +/** Get nearest up-rounded power of 2 */ +#define LOG2_CEIL(x) (1 << log2i((x) - 1) + 1) /** Calculate the number of elements in an array. */ #define ARRAY_LEN(a) ( sizeof (a) / sizeof (a)[0] ) @@ -212,6 +216,13 @@ __attribute__((always_inline)) static inline uint64_t rdtsc() return tsc; } +/** Get log2 of long long integers */ +static inline int log2i(long long x) { + assert(x > 0); + + return sizeof(x) * 8 - __builtin_clzll(x) - 1; +} + /** Sleep with rdtsc */ void rdtsc_sleep(uint64_t nanosecs, uint64_t start); From efdc5cdff3497df222d47e81b28fae4185426c5a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 22 Oct 2016 20:47:36 -0400 Subject: [PATCH 024/211] added sample_{alloc,free} --- include/villas/sample.h | 9 +++++++-- lib/sample.c | 12 ++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/villas/sample.h b/include/villas/sample.h index 5d2db263d..7870d3cd9 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -60,8 +60,13 @@ struct sample { } data[]; }; -/** Request \p cnt samples from memory pool \p p and initialize them. */ -int sample_get_many(struct pool *p, struct sample *smps[], int cnt); +/** Request \p cnt samples from memory pool \p p and initialize them. + * This will leave the reference count of the sample to zero. + * Use the sample_get() function to increase it. */ +int sample_alloc(struct pool *p, struct sample *smps[], int cnt); + +/** Release an array of samples back to their pools */ +void sample_free(struct sample *smps[], int cnt); /** Increase reference count of sample */ int sample_get(struct sample *s); diff --git a/lib/sample.c b/lib/sample.c index f3040d3a0..058a2ad30 100644 --- a/lib/sample.c +++ b/lib/sample.c @@ -12,19 +12,27 @@ #include "sample.h" #include "timing.h" -int sample_get_many(struct pool *p, struct sample *smps[], int cnt) { +int sample_alloc(struct pool *p, struct sample *smps[], int cnt) { int ret; ret = pool_get_many(p, (void **) smps, cnt); if (ret < 0) return ret; - for (int i = 0; i < ret; i++) + for (int i = 0; i < ret; i++) { smps[i]->capacity = (p->blocksz - sizeof(**smps)) / sizeof(smps[0]->data[0]); + smps[i]->pool = p; + } return ret; } +void sample_free(struct sample *smps[], int cnt) +{ + for (int i = 0; i < cnt; i++) + pool_put(smps[i]->pool, smps[i]); +} + int sample_get(struct sample *s) { return atomic_fetch_add(&s->refcnt, 1) + 1; From 800e71bb96b891e1b245d6cd5c908dbfbb47eaae Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:05:29 -0400 Subject: [PATCH 025/211] proper return codes for incorrect CLI arguments --- src/hook.c | 4 ++-- src/pipe.c | 1 + src/signal.c | 1 + src/test.c | 11 ++--------- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/hook.c b/src/hook.c index a68a8bfae..7b04cd27e 100644 --- a/src/hook.c +++ b/src/hook.c @@ -53,8 +53,8 @@ int main(int argc, char *argv[]) break; case 'h': case '?': - usage(argv[0]); - exit(EXIT_SUCCESS); + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); } } diff --git a/src/pipe.c b/src/pipe.c index 626536b08..9cdb1cac1 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -203,6 +203,7 @@ int main(int argc, char *argv[]) case 'h': case '?': usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); } } diff --git a/src/signal.c b/src/signal.c index bce67fadd..2d47dfa95 100644 --- a/src/signal.c +++ b/src/signal.c @@ -102,6 +102,7 @@ int main(int argc, char *argv[]) case 'h': case '?': usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); } continue; diff --git a/src/test.c b/src/test.c index 4f9e351b9..a05e4b9ea 100644 --- a/src/test.c +++ b/src/test.c @@ -114,15 +114,8 @@ int main(int argc, char *argv[]) res = strtod(optarg, &endptr); goto check; case '?': - if (optopt == 'c') - error("Option -%c requires an argument.", optopt); - else if (isprint(optopt)) - error("Unknown option '-%c'.", optopt); - else - error("Unknown option character '\\x%x'.", optopt); - exit(EXIT_FAILURE); - default: - abort(); + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); } continue; From 510aec76309ba29cdb24b126930ff7946fda05ac Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:52:06 -0400 Subject: [PATCH 026/211] added constructor and destructor methods to hook_storage() management --- include/villas/hooks.h | 11 ++++++++++- lib/hooks.c | 9 ++++++++- lib/hooks/hooks-other.c | 8 ++++---- lib/hooks/hooks-stats.c | 12 ++---------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 8dbd4c09c..110e01ba6 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -74,6 +74,15 @@ struct hook_info { */ typedef int (*hook_cb_t)(struct hook *h, int when, struct hook_info *i); +/** Destructor callback for hook_storage() + * + * @param data A pointer to the data which should be destroyed. + */ +typedef void (*dtor_cb_t)(void *); + +/** Constructor callback for hook_storage() */ +typedef int (*ctor_cb_t)(void *); + enum hook_state { HOOK_DESTROYED, HOOK_INITIALIZED @@ -157,7 +166,7 @@ int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when); * @param len The size of hook prvate memory allocation. * @return A pointer to the allocated memory region or NULL after it was released. */ -void * hook_storage(struct hook *h, int when, size_t len); +void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_cb_t dtor); int hook_print(struct hook *h, int when, struct hook_info *j); int hook_ts(struct hook *h, int when, struct hook_info *j); diff --git a/lib/hooks.c b/lib/hooks.c index 5ffcc9044..daad04c42 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -75,14 +75,21 @@ int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when) return cnt; } -void * hook_storage(struct hook *h, int when, size_t len) +void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_cb_t dtor) { switch (when) { case HOOK_INIT: h->_vd = alloc(len); + + if (ctor) + ctor(h->_vd); + break; case HOOK_DESTROY: + if (dtor) + dtor(h->_vd); + free(h->_vd); h->_vd = NULL; break; diff --git a/lib/hooks/hooks-other.c b/lib/hooks/hooks-other.c index 86733cb19..0a63ea5fa 100644 --- a/lib/hooks/hooks-other.c +++ b/lib/hooks/hooks-other.c @@ -46,10 +46,10 @@ int hook_convert(struct hook *h, int when, struct hook_info *k) TO_FIXED, TO_FLOAT } mode; - } *private = hook_storage(h, when, sizeof(*private)); + } *private = hook_storage(h, when, sizeof(*private), NULL, NULL); switch (when) { - case HOOK_DESTROY: + case HOOK_PARSE: if (!h->parameter) error("Missing parameter for hook: '%s'", h->name); @@ -83,7 +83,7 @@ int hook_decimate(struct hook *h, int when, struct hook_info *j) struct { unsigned ratio; unsigned counter; - } *private = hook_storage(h, when, sizeof(*private)); + } *private = hook_storage(h, when, sizeof(*private), NULL, NULL); switch (when) { case HOOK_PARSE: @@ -123,7 +123,7 @@ int hook_skip_first(struct hook *h, int when, struct hook_info *j) struct { struct timespec skip; /**< Time to wait until first message is not skipped */ struct timespec until; /**< Absolute point in time from where we accept samples. */ - } *private = hook_storage(h, when, sizeof(*private)); + } *private = hook_storage(h, when, sizeof(*private), NULL, NULL); char *endptr; double wait; diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index 4b787b78f..e0139efff 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -17,13 +17,9 @@ extern struct list *hook_nodes; REGISTER_HOOK("stats", "Collect statistics for the current path", 2, 1, hook_stats, HOOK_STATS) int hook_stats(struct hook *h, int when, struct hook_info *j) { - struct stats *s = hook_storage(h, when, sizeof(struct stats)); + struct stats *s = hook_storage(h, when, sizeof(struct stats), (ctor_cb_t) stats_init, (dtor_cb_t) stats_destroy); switch (when) { - case HOOK_INIT: - stats_init(s); - break; - case HOOK_READ: assert(j->smps); @@ -31,11 +27,7 @@ int hook_stats(struct hook *h, int when, struct hook_info *j) break; case HOOK_PATH_STOP: - stats_print(s); - break; - - case HOOK_DESTROY: - stats_destroy(s); + stats_print(s, 1); break; case HOOK_PATH_RESTART: From 693329cb68303456ebd5dce1e5b4ad475d18d78f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:54:20 -0400 Subject: [PATCH 027/211] use hist_cnt_t throughout the histogram code --- include/villas/hist.h | 2 +- lib/hist.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/villas/hist.h b/include/villas/hist.h index 11be82119..a410e3649 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -21,7 +21,7 @@ #define HIST_HEIGHT (LOG_WIDTH - 55) #define HIST_SEQ 17 -typedef unsigned hist_cnt_t; +typedef uintmax_t hist_cnt_t; /** Histogram structure used to collect statistics. */ struct hist { diff --git a/lib/hist.c b/lib/hist.c index 33bbce263..a1ff40aac 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -103,7 +103,7 @@ double hist_stddev(struct hist *h) void hist_print(struct hist *h) { INDENT - stats("Counted values: %u (%u between %f and %f)", h->total, h->total-h->higher-h->lower, h->high, h->low); + stats("Counted values: %ju (%ju between %f and %f)", h->total, h->total-h->higher-h->lower, h->high, h->low); stats("Highest: %f Lowest: %f", h->highest, h->lowest); stats("Mu: %f Sigma2: %f Sigma: %f", hist_mean(h), hist_var(h), hist_stddev(h)); @@ -135,11 +135,11 @@ void hist_plot(struct hist *h) for (int i = 0; i < h->length; i++) { double value = VAL(h, i); - int cnt = h->data[i]; + hist_cnt_t cnt = h->data[i]; int bar = HIST_HEIGHT * ((double) cnt / max); if (value > h->lowest || value < h->highest) - stats("%+9g | " "%5u" " | %.*s", value, cnt, bar, buf); + stats("%+9g | %5ju | %.*s", value, cnt, bar, buf); } } @@ -150,7 +150,7 @@ char * hist_dump(struct hist *h) strcatf(&buf, "[ "); for (int i = 0; i < h->length; i++) - strcatf(&buf, "%u ", h->data[i]); + strcatf(&buf, "%ju ", h->data[i]); strcatf(&buf, "]"); @@ -199,9 +199,9 @@ int hist_dump_matlab(struct hist *h, FILE *f) fprintf(f, "%lu = struct( ", time(NULL)); fprintf(f, "'low', %f, ", h->low); fprintf(f, "'high', %f, ", h->high); - fprintf(f, "'total', %u, ", h->total); - fprintf(f, "'higher', %u, ", h->higher); - fprintf(f, "'lower', %u, ", h->lower); + fprintf(f, "'total', %ju, ", h->total); + fprintf(f, "'higher', %ju, ", h->higher); + fprintf(f, "'lower', %ju, ", h->lower); fprintf(f, "'highest', %f, ", h->highest); fprintf(f, "'lowest', %f, ", h->lowest); fprintf(f, "'mean', %f, ", hist_mean(h)); From c0d5bbb47b8f26914fa256bb835caa8369a13a67 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:55:12 -0400 Subject: [PATCH 028/211] add a couple of NULL pointer checks for bucket-less histograms --- lib/hist.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/hist.c b/lib/hist.c index a1ff40aac..b57eaacb0 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -24,15 +24,25 @@ void hist_create(struct hist *h, double low, double high, double resolution) h->low = low; h->high = high; h->resolution = resolution; - h->length = (high - low) / resolution; - h->data = alloc(h->length * sizeof(unsigned)); + + if (resolution > 0) { + h->length = (high - low) / resolution; + h->data = alloc(h->length * sizeof(unsigned)); + } + else { + h->length = 0; + h->data = NULL; + } hist_reset(h); } void hist_destroy(struct hist *h) { - free(h->data); + if (h->data) { + free(h->data); + h->data = NULL; + } } void hist_put(struct hist *h, double value) @@ -52,7 +62,7 @@ void hist_put(struct hist *h, double value) h->higher++; else if (idx < 0) h->lower++; - else + else if (h->data != NULL) h->data[idx]++; h->total++; @@ -83,7 +93,8 @@ void hist_reset(struct hist *h) h->highest = DBL_MIN; h->lowest = DBL_MAX; - memset(h->data, 0, h->length * sizeof(unsigned)); + if (h->data) + memset(h->data, 0, h->length * sizeof(unsigned)); } double hist_mean(struct hist *h) From 3d694cf4d921b8e202dd68480e8521835f607faf Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:55:56 -0400 Subject: [PATCH 029/211] add possibility to print histogram in different verbosity levels --- include/villas/hist.h | 2 +- lib/hist.c | 4 ++-- src/test.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/villas/hist.h b/include/villas/hist.h index a410e3649..abb3ea091 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -67,7 +67,7 @@ double hist_mean(struct hist *h); double hist_stddev(struct hist *h); /** Print all statistical properties of distribution including a graphilcal plot of the histogram. */ -void hist_print(struct hist *h); +void hist_print(struct hist *h, int details); /** Print ASCII style plot of histogram */ void hist_plot(struct hist *h); diff --git a/lib/hist.c b/lib/hist.c index b57eaacb0..21baa6784 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -112,13 +112,13 @@ double hist_stddev(struct hist *h) return sqrt(hist_var(h)); } -void hist_print(struct hist *h) +void hist_print(struct hist *h, int details) { INDENT stats("Counted values: %ju (%ju between %f and %f)", h->total, h->total-h->higher-h->lower, h->high, h->low); stats("Highest: %f Lowest: %f", h->highest, h->lowest); stats("Mu: %f Sigma2: %f Sigma: %f", hist_mean(h), hist_var(h), hist_stddev(h)); - if (h->total - h->higher - h->lower > 0) { + if (details > 0 && h->total - h->higher - h->lower > 0) { char *buf = hist_dump(h); stats("Matlab: %s", buf); free(buf); diff --git a/src/test.c b/src/test.c index a05e4b9ea..bb31796d0 100644 --- a/src/test.c +++ b/src/test.c @@ -182,7 +182,7 @@ void test_rtt() { else error("Invalid file descriptor: %u", fd); - hist_print(&hist); + hist_print(&hist, 1); hist_destroy(&hist); } From 0d58df66e75f36192bb14a06000dddf04754d0e7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:57:05 -0400 Subject: [PATCH 030/211] fixed segmentation fault in villas-pipe --- src/pipe.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pipe.c b/src/pipe.c index afd57e7b6..2226c917d 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -49,15 +49,14 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) if (recvv.started) { pthread_cancel(recvv.thread); pthread_join(recvv.thread, NULL); + pool_destroy(&recvv.pool); } if (sendd.started) { pthread_cancel(sendd.thread); pthread_join(sendd.thread, NULL); + pool_destroy(&sendd.pool); } - - pool_destroy(&recvv.pool); - pool_destroy(&sendd.pool); node_stop(node); node_deinit(node->_vt); @@ -96,7 +95,7 @@ static void * send_loop(void *ctx) sendd.started = true; /* Initialize memory */ - ret = pool_init(&sendd.pool, node->vectorize, SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); + ret = pool_init(&sendd.pool, LOG2_CEIL(node->vectorize), SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); if (ret < 0) error("Failed to allocate memory for receive pool."); @@ -140,7 +139,7 @@ static void * recv_loop(void *ctx) recvv.started = true; /* Initialize memory */ - ret = pool_init(&recvv.pool, node->vectorize, SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); + ret = pool_init(&recvv.pool, LOG2_CEIL(node->vectorize), SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); if (ret < 0) error("Failed to allocate memory for receive pool."); From 248a6638da6848a74a5349d52b9f1c9cf6dba17a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 22:57:58 -0400 Subject: [PATCH 031/211] these hooks do not use HOOK_{INIT,DEINIT} to lets return early to not fail the assertion --- lib/hooks/hooks-internal.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 070e68359..d10efb92e 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -16,6 +16,9 @@ REGISTER_HOOK("fix_ts", "Update timestamps of sample if not set", 0, 0, hook_fix int hook_fix_ts(struct hook *h, int when, struct hook_info *j) { struct timespec now = time_now(); + + if (when != HOOK_READ) + return 0; assert(j->smps); @@ -41,6 +44,9 @@ int hook_fix_ts(struct hook *h, int when, struct hook_info *j) REGISTER_HOOK("restart", "Call restart hooks for current path", 1, 1, hook_restart, HOOK_INTERNAL | HOOK_READ) int hook_restart(struct hook *h, int when, struct hook_info *j) { + if (when != HOOK_READ) + return 0; + assert(j->smps); assert(j->path); @@ -68,6 +74,9 @@ int hook_drop(struct hook *h, int when, struct hook_info *j) { int i, ok, dist; + if (when != HOOK_READ) + return 0; + assert(j->smps); for (i = 0, ok = 0; i < j->cnt; i++) { From 287e5727fba5dde8ad085a49f39f8ddaee4b0f43 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 23:00:17 -0400 Subject: [PATCH 032/211] fix block size calculation for memory pool --- lib/pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pool.c b/lib/pool.c index 955b8b77a..7db22d59c 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -18,7 +18,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype * /* Make sure that we use a block size that is aligned to the size of a cache line */ p->alignment = kernel_get_cacheline_size(); - p->blocksz = blocksz * CEIL(blocksz, p->alignment); + p->blocksz = p->alignment * CEIL(blocksz, p->alignment); p->len = cnt * p->blocksz; p->mem = m; From 3d22238976174ea2d2ac43ba549f19fb8198e1cd Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 30 Oct 2016 23:01:14 -0400 Subject: [PATCH 033/211] make pool initialisation more robust by allowing non-pow2 pool sizes (we will use the next bigger power-of-2 for the internal queue) --- lib/pool.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/pool.c b/lib/pool.c index 7db22d59c..df187790b 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -25,10 +25,8 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype * p->buffer = memory_alloc_aligned(m, p->len, p->alignment); if (!p->buffer) serror("Failed to allocate memory for memory pool"); - else - debug(DBG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); - ret = queue_init(&p->queue, cnt, m); + ret = queue_init(&p->queue, LOG2_CEIL(cnt), m); if (ret) return ret; From dd7e0443ced2d1bae4303751cf176c30fd50cc0a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 21:30:28 -0500 Subject: [PATCH 034/211] add node id to web mockup javascript --- include/villas/webmsg_format.h | 8 ++++---- web/socket/app.js | 2 +- web/socket/msg.js | 3 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/villas/webmsg_format.h b/include/villas/webmsg_format.h index 55f885980..c6b0e0d4d 100644 --- a/include/villas/webmsg_format.h +++ b/include/villas/webmsg_format.h @@ -49,9 +49,9 @@ /** Initialize a message with default values */ #define WEBMSG_INIT(len, seq) (struct msg) {\ - .version = MSG_VERSION, \ - .type = MSG_TYPE_DATA, \ - .endian = MSG_ENDIAN_HOST, \ + .version = WEBMSG_VERSION, \ + .type = WEBMSG_TYPE_DATA, \ + .endian = WEBMSG_ENDIAN_HOST, \ .length = len, \ .sequence = seq \ } @@ -80,7 +80,7 @@ struct webmsg unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #endif - uint8_t node_id; /**< The node index from / to which this sample received / sent to. + uint8_t id; /**< The node index from / to which this sample received / sent to. * Corresponds to the index of the node in the http://localhost/nodes.json array. */ uint16_t length; /**< The number of values in msg::data[]. Endianess is specified in msg::endian. */ diff --git a/web/socket/app.js b/web/socket/app.js index a1b584dca..8bf88f94b 100644 --- a/web/socket/app.js +++ b/web/socket/app.js @@ -174,7 +174,7 @@ function wsConnect(url, protocol) { connection.onmessage = function(e) { var msgs = Msg.fromArrayBufferVector(e.data); - console.log('Received ' + msgs.length + ' messages with ' + msgs[0].data.length + ' values: ' + msgs[0].timestamp); + console.log('Received ' + msgs.length + ' messages with ' + msgs[0].data.length + ' values from id ' + msgs[0].id + ' with timestamp ' + msgs[0].timestamp); for (var j = 0; j < plotData.length; j++) { // remove old diff --git a/web/socket/msg.js b/web/socket/msg.js index a23795197..75436e396 100644 --- a/web/socket/msg.js +++ b/web/socket/msg.js @@ -20,6 +20,7 @@ function Msg(c, d) this.endian = typeof c.endian === 'undefined' ? Msg.prototype.ENDIAN_LITTLE : c.endian; this.version = typeof c.version === 'undefined' ? Msg.prototype.VERSION : c.version; this.type = typeof c.type === 'undefined' ? Msg.prototype.TYPE_DATA : c.type; + this.id = typeof c.id === 'undefined' ? -1 : c.id; this.timestamp = typeof c.timestamp === 'undefined' ? Date.now() : c.timestamp; if (Array.isArray(d)) { @@ -55,6 +56,7 @@ Msg.fromArrayBuffer = function(data) endian: (bits >> Msg.prototype.OFFSET_ENDIAN) & 0x1, version: (bits >> Msg.prototype.OFFSET_VERSION) & 0xF, type: (bits >> Msg.prototype.OFFSET_TYPE) & 0x3, + id: data.getUint8( 0x01, endian), length: data.getUint16(0x02, endian), sequence: data.getUint32(0x04, endian), timestamp: data.getUint32(0x08, endian) * 1e3 + @@ -109,6 +111,7 @@ Msg.prototype.toArrayBuffer = function() var nsec = (this.timestamp - sec * 1e3) * 1e6; view.setUint8( 0x00, bits, true); + view.setUint8( 0x01, this.id, true); view.setUint16(0x02, this.length, true); view.setUint32(0x04, this.sequence, true); view.setUint32(0x08, sec, true); From 88e36f272b54c6dacc4d267ee322c8e1ee3129cc Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 22:15:00 -0500 Subject: [PATCH 035/211] fix calculation of log2i(1) --- include/villas/utils.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/villas/utils.h b/include/villas/utils.h index 0e29fba8e..e6ef0e469 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -221,7 +221,8 @@ __attribute__((always_inline)) static inline uint64_t rdtsc() /** Get log2 of long long integers */ static inline int log2i(long long x) { - assert(x > 0); + if (x == 0) + return 1; return sizeof(x) * 8 - __builtin_clzll(x) - 1; } From b23484550f01455a602388ac16c27bdfd5eff321 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 22:17:45 -0500 Subject: [PATCH 036/211] major rewrite with MPMC queues --- include/villas/path.h | 54 +++++---- lib/cfg.c | 78 +++++++------ lib/path.c | 265 ++++++++++++++++++++++++++++-------------- 3 files changed, 248 insertions(+), 149 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index 0bcb4cf56..7bf71a003 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -26,55 +26,50 @@ #include "hooks.h" #include "queue.h" #include "pool.h" +#include "stats.h" -/** The datastructure for a path. - * - * @todo Add support for multiple outgoing nodes - */ +struct path_source +{ + struct node *node; + struct pool pool; + int samplelen; + pthread_t tid; +}; + +struct path_destination +{ + struct node *node; + struct queue queue; + int queuelen; + pthread_t tid; +}; + +/** The datastructure for a path. */ struct path { enum { PATH_INVALID, /**< Path is invalid. */ - PATH_CREATED, /**< Path has been created: lists initialized */ PATH_INITIALIZED, /**< Path queues, memory pools & hook system initialized. */ PATH_RUNNING, /**< Path is currently running. */ PATH_STOPPED, /**< Path has been stopped. */ PATH_DESTROYED /**< Path is destroyed. */ } state; /**< Path state */ - struct node *in; /**< Pointer to the incoming node */ - - struct queue queue; /**< A ring buffer for all received messages (unmodified) */ - struct pool pool; /**< Memory pool for messages / samples. */ + /* Each path has a single source and multiple destinations */ + struct path_source *source; /**< Pointer to the incoming node */ + struct list destinations; /**< List of all outgoing nodes (struct path_destination). */ - struct list destinations; /**< List of all outgoing nodes */ struct list hooks; /**< List of function pointers to hooks */ - int samplelen; /**< Maximum number of values per sample for this path. */ - int queuelen; /**< Size of sample queue for this path. */ int enabled; /**< Is this path enabled */ pthread_t tid; /**< The thread id for this path */ - - config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ char *_name; /**< Singleton: A string which is used to print this path to screen. */ - /** The following fields are mostly managed by hook_ functions @{ */ + struct stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ - struct { - struct hist owd; /**< Histogram for one-way-delay (OWD) of received messages */ - struct hist gap_msg; /**< Histogram for inter message timestamps (as sent by remote) */ - struct hist gap_recv; /**< Histogram for inter message arrival time (as seen by this instance) */ - struct hist gap_seq; /**< Histogram of sequence number displacement of received messages */ - } hist; - - /* Statistic counters */ - uintmax_t invalid; /**< Counter for invalid messages */ - uintmax_t skipped; /**< Counter for skipped messages due to hooks */ - uintmax_t dropped; /**< Counter for dropped messages due to reordering */ - - /** @} */ + config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ }; /** Initialize internal data structures. */ @@ -119,6 +114,9 @@ void path_print_stats(struct path *p); */ const char * path_name(struct path *p); +/** Reverse a path */ +int path_reverse(struct path *p, struct path *r); + /** Check if node is used as source or destination of a path. */ int path_uses_node(struct path *p, struct node *n); diff --git a/lib/cfg.c b/lib/cfg.c index a541de4c1..038744dc9 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -149,14 +149,14 @@ int cfg_parse_path(config_setting_t *cfg, { config_setting_t *cfg_out, *cfg_hook; const char *in; - int ret, reverse; + int ret, reverse, samplelen, queuelen; struct path *p; + + struct node *source; + struct list destinations; /* Allocate memory and intialize path structure */ p = alloc(sizeof(struct path)); - - list_init(&p->destinations); - list_init(&p->hooks); /* Input node */ if (!config_setting_lookup_string(cfg, "in", &in) && @@ -165,8 +165,8 @@ int cfg_parse_path(config_setting_t *cfg, !config_setting_lookup_string(cfg, "source", &in)) cerror(cfg, "Missing input node for path"); - p->in = list_lookup(nodes, in); - if (!p->in) + source = list_lookup(nodes, in); + if (!source) cerror(cfg, "Invalid input node '%s'", in); /* Output node(s) */ @@ -177,58 +177,66 @@ int cfg_parse_path(config_setting_t *cfg, !(cfg_out = config_setting_get_member(cfg, "sink"))) cerror(cfg, "Missing output nodes for path"); - ret = cfg_parse_nodelist(cfg_out, &p->destinations, nodes); + list_init(&destinations); + ret = cfg_parse_nodelist(cfg_out, &destinations, nodes); if (ret <= 0) cerror(cfg_out, "Invalid output nodes"); - - /* Check if nodes are suitable */ - if (p->in->_vt->read == NULL) - cerror(cfg, "Input node '%s' is not supported as a source.", node_name(p->in)); - - list_foreach(struct node *n, &p->destinations) { - if (n->_vt->write == NULL) - cerror(cfg_out, "Output node '%s' is not supported as a destination.", node_name(n)); - } /* Optional settings */ + list_init(&p->hooks); cfg_hook = config_setting_get_member(cfg, "hook"); if (cfg_hook) cfg_parse_hooklist(cfg_hook, &p->hooks); - if (!config_setting_lookup_int(cfg, "values", &p->samplelen)) - p->samplelen = DEFAULT_VALUES; - if (!config_setting_lookup_int(cfg, "queuelen", &p->queuelen)) - p->queuelen = DEFAULT_QUEUELEN; if (!config_setting_lookup_bool(cfg, "reverse", &reverse)) reverse = 0; if (!config_setting_lookup_bool(cfg, "enabled", &p->enabled)) p->enabled = 1; + if (!config_setting_lookup_int(cfg, "values", &samplelen)) + samplelen = DEFAULT_VALUES; + if (!config_setting_lookup_int(cfg, "queuelen", &queuelen)) + queuelen = DEFAULT_QUEUELEN; - if (!IS_POW2(p->queuelen)) { - p->queuelen = LOG2_CEIL(p->queuelen); - warn("Queue length should always be a power of 2. Adjusting to %d", p->queuelen); + if (!IS_POW2(queuelen)) { + queuelen = LOG2_CEIL(queuelen); + warn("Queue length should always be a power of 2. Adjusting to %d", queuelen); } p->cfg = cfg; + + /* Check if nodes are suitable */ + if (source->_vt->read == NULL) + cerror(cfg, "Input node '%s' is not supported as a source.", node_name(source)); + + p->source = alloc(sizeof(struct path_source)); + p->source->node = source; + p->source->samplelen = samplelen; + + list_foreach(struct node *n, &destinations) { + if (n->_vt->write == NULL) + cerror(cfg_out, "Output node '%s' is not supported as a destination.", node_name(n)); + + struct path_destination *pd = alloc(sizeof(struct path_destination)); + + pd->node = n; + pd->queuelen = queuelen; + + list_push(&p->destinations, pd); + } list_push(paths, p); if (reverse) { - if (list_length(&p->destinations) > 1) - cerror(cfg, "Can't reverse path with multiple destination nodes"); - - struct path *r = memdup(p, sizeof(struct path)); - path_init(r); - - /* Swap source and destination node */ - r->in = list_first(&p->destinations); - list_push(&r->destinations, p->in); - - if (cfg_hook) - cfg_parse_hooklist(cfg_hook, &r->hooks); + struct path *r = alloc(sizeof(struct path)); + + ret = path_reverse(p, r); + if (ret) + cerror(cfg, "Failed to reverse path %s", path_name(p)); list_push(paths, r); } + + list_destroy(&destinations, NULL, false); return 0; } diff --git a/lib/path.c b/lib/path.c index 7d22f768e..4a9045072 100644 --- a/lib/path.c +++ b/lib/path.c @@ -19,74 +19,103 @@ #include "pool.h" #include "queue.h" +static void path_read(struct path *p) +{ + int recv; + int enqueue; + int enqueued; + int ready = 0; /**< Number of blocks in smps[] which are allocated and ready to be used by node_read(). */ + + struct path_source *ps = p->source; + + int cnt = ps->node->vectorize; + + struct sample *smps[cnt]; + + /* Fill smps[] free sample blocks from the pool */ + ready += sample_alloc(&ps->pool, smps, cnt - ready); + if (ready != cnt) + warn("Pool underrun for path %s", path_name(p)); + + /* Read ready samples and store them to blocks pointed by smps[] */ + recv = node_read(ps->node, smps, ready); + if (recv < 0) + error("Failed to receive message from node %s", node_name(ps->node)); + else if (recv < ready) + warn("Partial read for path %s: read=%u expected=%u", path_name(p), recv, ready); + + debug(DBG_PATH | 15, "Received %u messages from node %s", recv, node_name(ps->node)); + + /* Run preprocessing hooks for vector of samples */ + enqueue = hook_run(p, smps, recv, HOOK_READ); + if (enqueue != recv) { + info("Hooks skipped %u out of %u samples for path %s", recv - enqueue, recv, path_name(p)); + + stats_update(p->stats, STATS_SKIPPED, recv - enqueue); + } + + list_foreach(struct path_destination *pd, &p->destinations) { + enqueued = queue_push_many(&pd->queue, (void **) smps, enqueue); + if (enqueue != enqueued) + warn("Queue overrun for path %s", path_name(p)); + + for (int i = 0; i < enqueued; i++) + sample_get(smps[i]); /* increase reference count */ + + debug(DBG_PATH | 15, "Enqueued %u samples to queue of path %s", enqueued, path_name(p)); + } +} + +static void path_write(struct path *p) +{ + list_foreach(struct path_destination *pd, &p->destinations) { + int cnt = pd->node->vectorize; + int sent; + int tosend; + int available; + int released; + + struct sample *smps[cnt]; + + /* As long as there are still samples in the queue */ + while (1) { + available = queue_pull_many(&pd->queue, (void **) smps, cnt); + if (available == 0) + break; + else if (available < cnt) + warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); + + debug(DBG_PATH | 15, "Dequeued %u samples from queue of node %s which is part of path %s", available, node_name(pd->node), path_name(p)); + + tosend = hook_run(p, smps, available, HOOK_WRITE); + if (tosend == 0) + continue; + + sent = node_write(pd->node, smps, tosend); + if (sent < 0) + error("Failed to sent %u samples to node %s", cnt, node_name(pd->node)); + else if (sent < tosend) + warn("Partial write to node %s", node_name(pd->node)); + + debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(pd->node)); + + released = 0; + for (int i = 0; i < sent; i++) + released += sample_put(smps[i]); + + debug(DBG_PATH | 15, "Released %d samples back to memory pool", released); + } + } +} + /** Main thread function per path: receive -> sent messages */ static void * path_run(void *arg) { struct path *p = arg; - unsigned cnt = p->in->vectorize; - int recv, enqueue, enqueued; - int ready = 0; /**< Number of blocks in smps[] which are allocated and ready to be used by node_read(). */ - struct sample *smps[cnt]; - /* Main thread loop */ for (;;) { - /* Fill smps[] free sample blocks from the pool */ - ready += sample_get_many(&p->pool, smps, cnt - ready); - if (ready != cnt) - warn("Pool underrun for path %s", path_name(p)); - - /* Read ready samples and store them to blocks pointed by smps[] */ - recv = p->in->_vt->read(p->in, smps, ready); - if (recv < 0) - error("Failed to receive message from node %s", node_name(p->in)); - else if (recv < ready) - warn("Partial read for path %s: read=%u expected=%u", path_name(p), recv, ready); - - debug(DBG_PATH | 15, "Received %u messages from node %s", recv, node_name(p->in)); - - /* Run preprocessing hooks for vector of samples */ - enqueue = hook_run(p, smps, recv, HOOK_READ); - if (enqueue != recv) { - info("Hooks skipped %u out of %u samples for path %s", recv - enqueue, recv, path_name(p)); - p->skipped += recv - enqueue; - } - - enqueued = queue_push_many(&p->queue, (void **) smps, enqueue); - if (enqueue != enqueued) - warn("Failed to enqueue %u samples for path %s", enqueue - enqueued, path_name(p)); - - ready -= enqueued; - - debug(DBG_PATH | 3, "Enqueuing %u samples to queue of path %s", enqueue, path_name(p)); - - list_foreach(struct node *n, &p->destinations) { - int cnt = n->vectorize; - int sent, tosend, available, released; - struct sample *smps[n->vectorize]; - - available = queue_pull_many(&p->queue, (void **) smps, cnt); - if (available < cnt) - warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); - - if (available == 0) - continue; - - tosend = hook_run(p, smps, available, HOOK_WRITE); - if (tosend == 0) - continue; - - sent = node_write(n, smps, tosend); - if (sent < 0) - error("Failed to sent %u samples to node %s", cnt, node_name(n)); - else if (sent < tosend) - warn("Partial write to node %s", node_name(n)); - - debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(n)); - - released = pool_put_many(&p->pool, (void **) smps, sent); - if (sent != released) - warn("Failed to release %u samples to pool for path %s", sent - released, path_name(p)); - } + path_read(p); + path_write(p); } return NULL; @@ -126,10 +155,10 @@ int path_stop(struct path *p) const char * path_name(struct path *p) { if (!p->_name) { - strcatf(&p->_name, "%s " MAG("=>"), node_name_short(p->in)); + strcatf(&p->_name, "%s " MAG("=>"), node_name_short(p->source->node)); - list_foreach(struct node *n, &p->destinations) - strcatf(&p->_name, " %s", node_name_short(n)); + list_foreach(struct path_destination *pd, &p->destinations) + strcatf(&p->_name, " %s", node_name_short(pd->node)); } return p->_name; @@ -137,18 +166,20 @@ const char * path_name(struct path *p) int path_init(struct path *p) { - int ret; - + int ret, max_queuelen = 0; + /* Add internal hooks if they are not already in the list*/ list_foreach(struct hook *h, &hooks) { - if ((h->type & HOOK_INTERNAL) && (list_lookup(&p->hooks, h->name) == NULL)) + if ( + (h->type & HOOK_INTERNAL) && /* is internal hook? */ + (list_lookup(&p->hooks, h->name) == NULL) /* is not already in list? */ + ) list_push(&p->hooks, memdup(h, sizeof(struct hook))); } - + /* We sort the hooks according to their priority before starting the path */ list_sort(&p->hooks, hooks_sort_priority); - /* Allocate hook private memory for storing state / parameters */ ret = hook_run(p, NULL, 0, HOOK_INIT); if (ret) error("Failed to initialize hooks of path: %s", path_name(p)); @@ -157,36 +188,98 @@ int path_init(struct path *p) ret = hook_run(p, NULL, 0, HOOK_PARSE); if (ret) error("Failed to parse arguments for hooks of path: %s", path_name(p)); - - /* Initialize queue */ - ret = pool_init(&p->pool, SAMPLE_LEN(p->samplelen), p->queuelen, &memtype_hugepage); + + /* Initialize destinations */ + list_foreach(struct path_destination *pd, &p->destinations) { + ret = queue_init(&pd->queue, pd->queuelen, &memtype_hugepage); + if (ret) + error("Failed to initialize queue for path"); + + if (pd->queuelen > max_queuelen) + max_queuelen = pd->queuelen; + } + + /* Initialize source */ + ret = pool_init(&p->source->pool, max_queuelen, SAMPLE_LEN(p->source->samplelen), &memtype_hugepage); if (ret) error("Failed to allocate memory pool for path"); - ret = queue_init(&p->queue, p->queuelen, &memtype_hugepage); - if (ret) - error("Failed to initialize queue for path"); - p->state = PATH_INITIALIZED; return 0; } +void path_source_destroy(struct path_source *ps) +{ + pool_destroy(&ps->pool); +} + +void path_destination_destroy(struct path_destination *pd) +{ + queue_destroy(&pd->queue); +} + void path_destroy(struct path *p) { - hook_run(p, NULL, 0, HOOK_DEINIT); /* Release memory */ + list_destroy(&p->hooks, (dtor_cb_t) hook_destroy, true); + list_destroy(&p->destinations, (dtor_cb_t) path_destination_destroy, true); - list_destroy(&p->destinations, NULL, false); - list_destroy(&p->hooks, NULL, true); - - queue_destroy(&p->queue); - pool_destroy(&p->pool); - - p->state = PATH_DESTROYED; + path_source_destroy(p->source); free(p->_name); + free(p->source); + + p->state = PATH_DESTROYED; } int path_uses_node(struct path *p, struct node *n) { - return (p->in == n) || list_contains(&p->destinations, n) ? 0 : 1; + list_foreach(struct path_destination *pd, &p->destinations) { + if (pd->node == n) + return 0; + } + + return p->source->node == n ? 0 : -1; } + +int path_reverse(struct path *p, struct path *r) +{ + int ret; + + if (list_length(&p->destinations) > 1) + return -1; + + struct path_destination *first_pd = list_first(&p->destinations); + + list_init(&r->destinations); + list_init(&r->hooks); + + /* General */ + r->enabled = p->enabled; + r->cfg = p->cfg; + + struct path_destination *pd = alloc(sizeof(struct path_destination)); + + pd->node = p->source->node; + pd->queuelen = first_pd->queuelen; + + list_push(&r->destinations, pd); + + struct path_source *ps = alloc(sizeof(struct path_source)); + + ps->node = first_pd->node; + ps->samplelen = p->source->samplelen; + + r->source = ps; + + list_foreach(struct hook *h, &p->hooks) { + struct hook *hc = alloc(sizeof(struct hook)); + + ret = hook_copy(h, hc); + if (ret) + return ret; + + list_push(&r->hooks, hc); + } + + return 0; +} \ No newline at end of file From 735f08f55121026662e57b2ec748e029f52f20af Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 22:18:26 -0500 Subject: [PATCH 037/211] more improvements to make statistic subsystem extensible --- include/villas/stats.h | 38 +++++---- lib/hooks/hooks-internal.c | 2 +- lib/stats.c | 162 ++++++++++++++++++++++--------------- 3 files changed, 124 insertions(+), 78 deletions(-) diff --git a/include/villas/stats.h b/include/villas/stats.h index e6260833b..49d6e11ef 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -23,20 +23,24 @@ struct sample; struct path; struct node; -struct stats { - struct { - uintmax_t invalid; /**< Counter for invalid messages */ - uintmax_t skipped; /**< Counter for skipped messages due to hooks */ - uintmax_t dropped; /**< Counter for dropped messages due to reordering */ - } counter; +enum stats_id { + STATS_INVALID, /**< Counter for invalid messages */ + STATS_SKIPPED, /**< Counter for skipped messages due to hooks */ + STATS_DROPPED, /**< Counter for dropped messages due to reordering */ + STATS_GAP_SEQUENCE, /**< Histogram of sequence number displacement of received messages */ + STATS_GAP_SAMPLE, /**< Histogram for inter message timestamps (as sent by remote) */ + STATS_GAP_RECEIVED, /**< Histogram for inter message arrival time (as seen by this instance) */ + STATS_OWD, /**< Histogram for one-way-delay (OWD) of received messages */ + STATS_COUNT /**< Just here to have an updated number of statistics */ +}; + +struct stats_delta { + double vals[STATS_COUNT]; +}; + +struct stats { + struct hist histograms[STATS_COUNT]; - struct { - struct hist owd; /**< Histogram for one-way-delay (OWD) of received messages */ - struct hist gap_msg; /**< Histogram for inter message timestamps (as sent by remote) */ - struct hist gap_recv; /**< Histogram for inter message arrival time (as seen by this instance) */ - struct hist gap_seq; /**< Histogram of sequence number displacement of received messages */ - } histogram; - struct sample *last; }; @@ -44,8 +48,14 @@ int stats_init(struct stats *s); void stats_destroy(struct stats *s); +void stats_update(struct stats *s, enum stats_id id, double val); + +int stats_commit(struct stats *s, struct stats_delta *d); + void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); +void stats_decollect(struct stats *s, struct sample *smps[], size_t cnt); + #ifdef WITH_JANSSON json_t * stats_json(struct stats *s); #endif @@ -56,7 +66,7 @@ void stats_print_header(); void stats_print_periodic(struct stats *s, struct path *p); -void stats_print(struct stats *s); +void stats_print(struct stats *s, int details); void stats_send(struct stats *s, struct node *n); diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index d10efb92e..cb91505fd 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -85,7 +85,7 @@ int hook_drop(struct hook *h, int when, struct hook_info *j) if (h->prev) { dist = h->last->sequence - (int32_t) h->prev->sequence; if (dist <= 0) { - j->path->stats->counter.dropped++; + stats_update(j->path->stats, STATS_DROPPED, dist); warn("Dropped sample: dist = %d, i = %d", dist, i); } else { diff --git a/lib/stats.c b/lib/stats.c index f25675d1d..5bcceee21 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -13,38 +13,81 @@ #include "sample.h" #include "log.h" +static struct stats_desc { + const char *name; + const char *unit; + const char *desc; + struct { + double min; + double max; + double resolution; + } hist; +} stats_table[] = { + { "invalid", "", "invalid messages", {0, 0, -1, }}, + { "skipped", "", "skipped messages by hooks", {0, 0, -1, }}, + { "dropped", "", "dropped messages because of reordering", {0, 0, -1, }}, + { "gap_sequence", "", "sequence number displacement of received messages", {-10, 10, 20, }}, + { "gap_sample", "", "inter message timestamps (as sent by remote)", {90e-3, 110e-3, 1e-3, }}, + { "gap_received", "", "Histogram for inter message arrival time (as seen by this instance)", {90e-3, 110e-3, 1e-3, }}, + { "owd", "s", "Histogram for one-way-delay (OWD) of received messages", {0, 1, 100e-3, }} +}; + int stats_init(struct stats *s) { - /** @todo Allow configurable bounds for histograms */ - hist_create(&s->histogram.owd, 0, 1, 100e-3); - hist_create(&s->histogram.gap_msg, 90e-3, 110e-3, 1e-3); - hist_create(&s->histogram.gap_recv, 90e-3, 110e-3, 1e-3); - hist_create(&s->histogram.gap_seq, -HIST_SEQ, +HIST_SEQ, 1); - + for (int i = 0; i < STATS_COUNT; i++) { + struct stats_desc *desc = &stats_table[i]; + hist_create(&s->histograms[i], desc->hist.min, desc->hist.max, desc->hist.resolution); + } + return 0; } void stats_destroy(struct stats *s) { - hist_destroy(&s->histogram.owd); - hist_destroy(&s->histogram.gap_msg); - hist_destroy(&s->histogram.gap_recv); - hist_destroy(&s->histogram.gap_seq); + for (int i = 0; i < STATS_COUNT; i++) { + hist_destroy(&s->histograms[i]); + } +} + +void stats_update(struct stats *s, enum stats_id id, double val) +{ + if (!s) + return; + + hist_put(&s->histograms[id], val); +} + +#if 0 +int stats_delta(struct stats_delta *d, struct sample *s, struct sample *p) +{ + d->histogram.owd = time_delta(&smps[i]->ts.origin, &smps[i]->ts.received); + d->histogram.gap = time_delta(&s->last->ts.origin, &smps[i]->ts.origin); + d->histogram.gap_seq = s->sequence - (int32_t) p->sequence; + d->histogram.gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received); + + d->counter.dropped = d->histogram.gap_seq <= 0 ? 1 : 0; + d->counter.invalid = 0; + + return 0; +} +#endif + +int stats_commit(struct stats *s, struct stats_delta *d) +{ + for (int i = 0; i < STATS_COUNT; i++) { + hist_put(&s->histograms[i], d->vals[i]); + } + + return 0; } void stats_collect(struct stats *s, struct sample *smps[], size_t cnt) { for (int i = 0; i < cnt; i++) { if (s->last) { - int gap_seq = smps[i]->sequence - (int32_t) s->last->sequence; - double owd = time_delta(&smps[i]->ts.origin, &smps[i]->ts.received); - double gap = time_delta(&s->last->ts.origin, &smps[i]->ts.origin); - double gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received); - - hist_put(&s->histogram.owd, owd); - hist_put(&s->histogram.gap_msg, gap); - hist_put(&s->histogram.gap_seq, gap_seq); - hist_put(&s->histogram.gap_recv, gap_recv); +// struct stats_delta d; +// stats_get_delta(&d, smps[i], s->last); +// stats_commit(s, &d); } if (i == 0 && s->last) @@ -59,30 +102,25 @@ void stats_collect(struct stats *s, struct sample *smps[], size_t cnt) #ifdef WITH_JANSSON json_t * stats_json(struct stats *s) { - return json_pack("{ s: { s: i, s: i, s: i }, s: { s: o, s: o, s: o } }", - "counter", - "dropped", s->counter.dropped, - "invalid", s->counter.invalid, - "skipped", s->counter.skipped, - "histogram", - "owd", hist_json(&s->histogram.owd), - "gap_msg", hist_json(&s->histogram.gap_msg), - "gap_recv",hist_json(&s->histogram.gap_recv), - "gap_seq", hist_json(&s->histogram.gap_seq) - ); + json_t *obj = json_object(); + + for (int i = 0; i < STATS_COUNT; i++) { + struct stats_desc *desc = &stats_table[i]; + + json_t *stats = hist_json(&s->histograms[i]); + + json_object_set(obj, desc->name, stats); + } + + return obj; } #endif void stats_reset(struct stats *s) { - s->counter.invalid = - s->counter.skipped = - s->counter.dropped = 0; - - hist_reset(&s->histogram.owd); - hist_reset(&s->histogram.gap_seq); - hist_reset(&s->histogram.gap_msg); - hist_reset(&s->histogram.gap_recv); + for (int i = 0; i < STATS_COUNT; i++) { + hist_reset(&s->histograms[i]); + } } void stats_print_header() @@ -101,41 +139,39 @@ void stats_print_header() void stats_print_periodic(struct stats *s, struct path *p) { - stats("%-40.40s|%10s|%10s|%10ju|%10ju|%10ju|", path_name(p), "", "", - s->counter.dropped, s->counter.skipped, s->counter.invalid); + stats("%-40.40s|%10f|%10f|%10ju|%10ju|%10ju|", path_name(p), + s->histograms[STATS_OWD].last, + 1.0 / s->histograms[STATS_GAP_SAMPLE].last, + s->histograms[STATS_DROPPED].total, + s->histograms[STATS_SKIPPED].total, + s->histograms[STATS_INVALID].total + ); } -void stats_print(struct stats *s) +void stats_print(struct stats *s, int details) { - stats("Dropped samples: %ju", s->counter.dropped); - stats("Skipped samples: %ju", s->counter.skipped); - stats("Invalid samples: %ju", s->counter.invalid); - - stats("One-way delay:"); - hist_print(&s->histogram.owd); - - stats("Inter-message arrival time:"); - hist_print(&s->histogram.gap_recv); - - stats("Inter-message ts gap:"); - hist_print(&s->histogram.gap_msg); - - stats("Inter-message sequence number gaps:"); - hist_print(&s->histogram.gap_seq); + for (int i = 0; i < STATS_COUNT; i++) { + struct stats_desc *desc = &stats_table[i]; + + stats("%s: %s", desc->name, desc->desc); + hist_print(&s->histograms[i], details); + } } void stats_send(struct stats *s, struct node *n) { - char buf[SAMPLE_LEN(16)]; + char buf[SAMPLE_LEN(STATS_COUNT * 5)]; struct sample *smp = (struct sample *) buf; int i = 0; - smp->data[i++].f = s->counter.invalid; /**< Use integer here? */ - smp->data[i++].f = s->counter.skipped; - smp->data[i++].f = s->counter.dropped; - smp->data[i++].f = s->histogram.owd.last, - smp->data[i++].f = 1.0 / s->histogram.gap_msg.last; - smp->data[i++].f = 1.0 / s->histogram.gap_recv.last; + + for (int j = 0; j < STATS_COUNT; j++) { + smp->data[i++].f = s->histograms[j].last; + smp->data[i++].f = s->histograms[j].highest; + smp->data[i++].f = s->histograms[j].lowest; + smp->data[i++].f = hist_mean(&s->histograms[j]); + smp->data[i++].f = hist_var(&s->histograms[j]); + } smp->length = i; node_write(n, &smp, 1); /* Send single message with statistics to destination node */ From 9e13b06a59e6a4fad18f4292bb62945afcea047d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 22:19:30 -0500 Subject: [PATCH 038/211] get first working version of web socket node-type with MPMC queues --- etc/websocket.conf | 3 +- include/villas/nodes/websocket.h | 17 +- include/villas/sample.h | 8 +- lib/nodes/websocket.c | 337 ++++++++++++++++++------------- thirdparty/libwebsockets | 2 +- 5 files changed, 214 insertions(+), 153 deletions(-) diff --git a/etc/websocket.conf b/etc/websocket.conf index 21e2513b8..2a012a0a3 100644 --- a/etc/websocket.conf +++ b/etc/websocket.conf @@ -33,7 +33,8 @@ nodes = { series = ( { label = "Random walk" }, { label = "Sine" }, - { label = "Rect" } + { label = "Rect" }, + { label = "Ramp" } ) } }; diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 4f3149534..9d4679d51 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -29,38 +29,35 @@ struct lws; /** Internal data per websocket node */ struct websocket { struct list connections; /**< List of active libwebsocket connections in server mode (struct websocket_connection) */ + struct list destinations; /**< List of struct lws_client_connect_info to connect to in client mode. */ struct pool pool; - struct queue queue_tx; /**< For samples which are sent to WebSockets */ - struct queue queue_rx; /**< For samples which are received from WebSockets */ - - qptr_t sent; - qptr_t received; - - int shutdown; + struct queue queue; /**< For samples which are received from WebSockets a */ + + int id; /**< The index of this node */ }; struct websocket_connection { enum { WEBSOCKET_ESTABLISHED, WEBSOCKET_ACTIVE, + WEBSOCKET_SHUTDOWN, WEBSOCKET_CLOSED } state; struct node *node; struct path *path; + struct queue queue; /**< For samples which are sent to the WebSocket */ + struct lws *wsi; struct { char name[64]; char ip[64]; } peer; - - qptr_t sent; - qptr_t received; }; /** @see node_vtable::init */ diff --git a/include/villas/sample.h b/include/villas/sample.h index c412f7127..4caf3f927 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -45,8 +45,6 @@ struct sample { atomic_int refcnt; /**< Reference counter. */ struct pool *pool; /**< This sample is belong to this memory pool. */ - - int endian; /**< Endianess of data in the sample. */ /** All timestamps are seconds / nano seconds after 1.1.1970 UTC */ struct { @@ -57,9 +55,9 @@ struct sample { /** The values. */ union { - float f; /**< Floating point values (note msg::endian) */ - uint32_t i; /**< Integer values (note msg::endian) */ - } data[]; + float f; /**< Floating point values. */ + uint32_t i; /**< Integer values. */ + } data[]; /**< Data is in host endianess! */ }; /** Request \p cnt samples from memory pool \p p and initialize them. diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index d7b51733c..901d1c8ce 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -16,6 +16,7 @@ #include #include "nodes/websocket.h" +#include "webmsg_format.h" #include "timing.h" #include "utils.h" #include "msg.h" @@ -33,43 +34,21 @@ static const char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS static const char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS */ static const char *htdocs; /**< Path to the directory which should be served by build in HTTP server */ +static int id = 0; + +struct list connections; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */ + /* Forward declarations */ static struct node_type vt; static int protocol_cb_http(struct lws *, enum lws_callback_reasons, void *, void *, size_t); static int protocol_cb_live(struct lws *, enum lws_callback_reasons, void *, void *, size_t); static struct lws_protocols protocols[] = { - { - "http-only", - protocol_cb_http, - 0, - 0 - }, - { - "live", - protocol_cb_live, - sizeof(struct websocket_connection), - 0 - }, - { 0 /* terminator */ } + { "http-only", protocol_cb_http, 0, 0 }, + { "live", protocol_cb_live, sizeof(struct websocket_connection), 0 }, + { NULL } }; -#if 0 -static const struct lws_extension exts[] = { - { - "permessage-deflate", - lws_extension_callback_pm_deflate, - "permessage-deflate" - }, - { - "deflate-frame", - lws_extension_callback_pm_deflate, - "deflate_frame" - }, - { NULL, NULL, NULL /* terminator */ } -}; -#endif - static void logger(int level, const char *msg) { int len = strlen(msg); if (strchr(msg, '\n')) @@ -80,7 +59,7 @@ static void logger(int level, const char *msg) { level = LLL_WARN; switch (level) { - case LLL_ERR: error("LWS: %.*s", len, msg); break; + case LLL_ERR: warn("LWS: %.*s", len, msg); break; case LLL_WARN: warn("LWS: %.*s", len, msg); break; case LLL_INFO: info("LWS: %.*s", len, msg); break; default: debug(DBG_WEBSOCKET | 1, "LWS: %.*s", len, msg); break; @@ -160,8 +139,9 @@ int protocol_cb_http(struct lws *wsi, enum lws_callback_reasons reason, void *us list_foreach(struct node *n, &vt.instances) { struct websocket *w = n->_vd; - json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i }", + json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i, s: i }", "name", node_name_short(n), + "id", w->id, "connections", list_length(&w->connections), "state", n->state, "vectorize", n->vectorize, @@ -228,7 +208,7 @@ int protocol_cb_http(struct lws *wsi, enum lws_callback_reasons reason, void *us } default: - break; + return 0; } return 0; @@ -242,6 +222,7 @@ try_to_reuse: int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { + int ret; struct websocket_connection *c = user; struct websocket *w; @@ -256,36 +237,63 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us return -1; } - /* Search for node whose name matches the URI. */ - c->node = list_lookup(&vt.instances, uri + 1); - if (c->node == NULL) { - warn("LWS: Closing Connection for non-existent node: %s", uri + 1); - return -1; + if ((uri[0] == '/' && uri[1] == 0) || uri[0] == 0){ + /* Catch all connection */ + c->node = NULL; } + else { + char *node = uri + 1; - /* Check if node is running */ - if (c->node->state != NODE_RUNNING) - return -1; + /* Search for node whose name matches the URI. */ + c->node = list_lookup(&vt.instances, node); + if (c->node == NULL) { + warn("LWS: Closing Connection for non-existent node: %s", uri + 1); + return -1; + } + + /* Check if node is running */ + if (c->node->state != NODE_RUNNING) + return -1; + } c->state = WEBSOCKET_ESTABLISHED; c->wsi = wsi; + + ret = queue_init(&c->queue, DEFAULT_QUEUELEN, &memtype_hugepage); + if (ret) { + warn("Failed to create queue for incoming websocket connection. Closing.."); + return -1; + } /* Lookup peer address for debug output */ lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi), c->peer.name, sizeof(c->peer.name), c->peer.ip, sizeof(c->peer.ip)); - info("LWS: New Connection for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); + if (c->node != NULL) + info("LWS: New connection for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); + else + info("LWS: New connection from %s (%s)", c->peer.name, c->peer.ip); - struct websocket *w = (struct websocket *) c->node->_vd; - list_push(&w->connections, c); + if (c->node != NULL) { + struct websocket *w = (struct websocket *) c->node->_vd; + list_push(&w->connections, c); + } + else { + list_push(&connections, c); + } return 0; } case LWS_CALLBACK_CLOSED: - info("LWS: Connection closed for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); + if (c->node != NULL) + info("LWS: Connection closed for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); + else + info("LWS: Connection closed from %s (%s)", c->peer.name, c->peer.ip); c->state = WEBSOCKET_CLOSED; c->wsi = NULL; + + queue_destroy(&c->queue); return 0; @@ -293,36 +301,30 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us case LWS_CALLBACK_SERVER_WRITEABLE: { w = (struct websocket *) c->node->_vd; - if (c->node->state != NODE_RUNNING) + if (c->node && c->node->state != NODE_RUNNING) return -1; - if (w->shutdown) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, (unsigned char *) "Bye", 4); + if (w->state == WEBSOCKET_SHUTDOWN) { + lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, (unsigned char *) "Node stopped", 4); return -1; } - - - int cnt, sent, ret; - unsigned char *bufs[DEFAULT_QUEUELEN]; - - cnt = queue_get_many(&w->queue_tx, (void **) bufs, DEFAULT_QUEUELEN, c->sent); - for (sent = 0; sent < cnt; sent++) { - struct msg *msg = (struct msg *) (bufs[sent] + LWS_PRE); + char *buf; + int cnt; + while ((cnt = queue_pull(&c->queue, (void **) &buf))) { + struct webmsg *msg = (struct webmsg *) (buf + LWS_PRE); - ret = lws_write(wsi, (unsigned char *) msg, MSG_LEN(msg->length), LWS_WRITE_BINARY); - if (ret < MSG_LEN(msg->length)) + pool_put(&w->pool, (void *) buf); + + ret = lws_write(wsi, (unsigned char *) msg, WEBMSG_LEN(msg->length), LWS_WRITE_BINARY); + if (ret < WEBMSG_LEN(msg->length)) error("Failed lws_write()"); if (lws_send_pipe_choked(wsi)) - break; + break; } - - queue_pull_many(&w->queue_tx, (void **) bufs, sent, &c->sent); - - pool_put_many(&w->pool, (void **) bufs, sent); - if (sent < cnt) + if (queue_available(&c->queue) > 0) lws_callback_on_writable(wsi); return 0; @@ -335,27 +337,30 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us if (c->node->state != NODE_RUNNING) return -1; - if (!lws_frame_is_binary(wsi) || len < MSG_LEN(0)) + if (!lws_frame_is_binary(wsi) || len < WEBMSG_LEN(0)) warn("LWS: Received invalid packet for node: %s", node_name(c->node)); - struct msg *msg = (struct msg *) in; + struct webmsg *msg = (struct webmsg *) in; - while ((char *) msg + MSG_LEN(msg->length) <= (char *) in + len) { - struct msg *msg2 = pool_get(&w->pool); + while ((char *) msg + WEBMSG_LEN(msg->length) <= (char *) in + len) { + struct webmsg *msg2 = pool_get(&w->pool); if (!msg2) { warn("Pool underrun for node: %s", node_name(c->node)); - return -1; + break; } - memcpy(msg2, msg, MSG_LEN(msg->length)); + memcpy(msg2, msg, WEBMSG_LEN(msg->length)); - queue_push(&w->queue_rx, msg2, &c->received); + ret = queue_push(&w->queue, msg2); + if (ret != 1) { + warn("Queue overrun for node: %s", node_name(c->node)); + break; + } /* Next message */ - msg = (struct msg *) ((char *) msg + MSG_LEN(msg->length)); + msg = (struct webmsg *) ((char *) msg + WEBMSG_LEN(msg->length)); } - /** @todo Implement */ return 0; } @@ -421,29 +426,24 @@ int websocket_deinit() int websocket_open(struct node *n) { - struct websocket *w = n->_vd; - int ret; + struct websocket *w = n->_vd; + + w->id = id++; list_init(&w->connections); list_init(&w->destinations); - size_t blocklen = LWS_PRE + MSG_LEN(DEFAULT_VALUES); + size_t blocklen = LWS_PRE + WEBMSG_LEN(DEFAULT_VALUES); - ret = pool_init_mmap(&w->pool, blocklen, 2 * DEFAULT_QUEUELEN); + ret = pool_init(&w->pool, 64 * DEFAULT_QUEUELEN, blocklen, &memtype_hugepage); if (ret) return ret; - ret = queue_init(&w->queue_tx, DEFAULT_QUEUELEN); + ret = queue_init(&w->queue, DEFAULT_QUEUELEN, &memtype_hugepage); if (ret) return ret; - - ret = queue_init(&w->queue_rx, DEFAULT_QUEUELEN); - if (ret) - return ret; - - queue_reader_add(&w->queue_rx, 0, 0); - + return 0; } @@ -451,13 +451,13 @@ int websocket_close(struct node *n) { struct websocket *w = n->_vd; - w->shutdown = 1; - - list_foreach(struct lws *wsi, &w->connections) - lws_callback_on_writable(wsi); + list_foreach(struct websocket_connection *c, &w->connections) { + c->state = WEBSOCKET_SHUTDOWN; + lws_callback_on_writable(c->wsi); + } pool_destroy(&w->pool); - queue_destroy(&w->queue_tx); + queue_destroy(&w->queue); list_destroy(&w->connections, NULL, false); @@ -475,17 +475,21 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt) { struct websocket *w = n->_vd; - struct msg *msgs[cnt]; + struct webmsg *msgs[cnt]; int got; - got = queue_pull_many(&w->queue_rx, (void **) msgs, cnt, &w->received); + do { + got = queue_pull_many(&w->queue, (void **) msgs, cnt); + pthread_yield(); + } while (got == 0); + for (int i = 0; i < got; i++) { smps[i]->sequence = msgs[i]->sequence; smps[i]->length = msgs[i]->length; - smps[i]->ts.origin = MSG_TS(msgs[i]); + smps[i]->ts.origin = WEBMSG_TS(msgs[i]); - memcpy(&smps[i]->data, &msgs[i]->data, MSG_DATA_LEN(msgs[i]->length)); + memcpy(&smps[i]->data, &msgs[i]->data, WEBMSG_DATA_LEN(msgs[i]->length)); } pool_put_many(&w->pool, (void **) msgs, got); @@ -493,59 +497,118 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt) return got; } +static int websocket_connection_init(struct websocket_connection *c) +{ + /** @todo */ + return -1; +} + +static void websocket_connection_destroy(struct websocket_connection *c) +{ + /** @todo */ +} + +static char * websocket_connection_name(struct websocket_connection *c) +{ + /** @todo */ + return "(todo)"; +} + +static int websocket_connection_write(struct websocket_connection *c, struct sample *smps[], unsigned cnt) +{ + int blocks, enqueued; + char *bufs[cnt]; + + switch (c->state) { + case WEBSOCKET_SHUTDOWN: + return -1; + case WEBSOCKET_CLOSED: + if (c->node) { + struct websocket *w = (struct websocket *) c->node->_vd; + list_remove(&w->connections, c); + } + else + list_remove(&connections, c); + break; + + case WEBSOCKET_ESTABLISHED: + c->state = WEBSOCKET_ACTIVE; + /* fall through */ + + case WEBSOCKET_ACTIVE: + blocks = pool_get_many(&w->pool, (void **) bufs, cnt); + if (blocks != cnt) + warn("Pool underrun in websocket connection: %s", websocket_connection_name(c)); + + for (int i = 0; i < blocks; i++) { + struct webmsg *msg = (struct webmsg *) (bufs[i] + LWS_PRE); + + msg->version = WEBMSG_VERSION; + msg->type = WEBMSG_TYPE_DATA; + msg->endian = WEBMSG_ENDIAN_HOST; + msg->length = smps[i]->length; + msg->sequence = smps[i]->sequence; + msg->id = w->id; + msg->ts.sec = smps[i]->ts.origin.tv_sec; + msg->ts.nsec = smps[i]->ts.origin.tv_nsec; + + memcpy(&msg->data, &smps[i]->data, smps[i]->length * 4); + } + + enqueued = queue_push_many(&c->queue, (void **) bufs, cnt); + if (enqueued != blocks) + warn("Queue overrun in websocket connection: %s", websocket_connection_name(c)); + + lws_callback_on_writable(c->wsi); + break; + } + + return 0; +} + int websocket_write(struct node *n, struct sample *smps[], unsigned cnt) { struct websocket *w = n->_vd; - int blocks, enqueued; - char *bufs[cnt]; - - /* Copy samples to websocket queue */ - blocks = pool_get_many(&w->pool, (void **) bufs, cnt); - if (blocks != cnt) - warn("Pool underrun in websocket node: %s", node_name(n)); - - for (int i = 0; i < blocks; i++) { - struct msg *msg = (struct msg *) (bufs[i] + LWS_PRE); - - msg->version = MSG_VERSION; - msg->type = MSG_TYPE_DATA; - msg->endian = MSG_ENDIAN_HOST; - msg->length = smps[i]->length; - msg->sequence = smps[i]->sequence; - msg->ts.sec = smps[i]->ts.origin.tv_sec; - msg->ts.nsec = smps[i]->ts.origin.tv_nsec; - - memcpy(&msg->data, &smps[i]->data, smps[i]->length * 4); + list_foreach(struct websocket_connection *c, &w->connections) { + websocket_write_connection(c, smps, cnt); } - enqueued = queue_push_many(&w->queue_tx, (void **) bufs, cnt, &w->sent); - if (enqueued != blocks) - warn("Queue overrun in websocket node: %s", node_name(n)); - - /* Notify all active websocket connections to send new data */ - list_foreach(struct websocket_connection *c, &w->connections) { - switch (c->state) { - case WEBSOCKET_CLOSED: - queue_reader_remove(&w->queue_tx, c->sent, w->sent); - list_remove(&w->connections, c); - break; - - case WEBSOCKET_ESTABLISHED: - c->sent = w->sent; - c->state = WEBSOCKET_ACTIVE; - - queue_reader_add(&w->queue_tx, c->sent, w->sent); - - case WEBSOCKET_ACTIVE: - lws_callback_on_writable(c->wsi); - break; - } + list_foreach(struct websocket_connection *c, &connections) { + websocket_write_connection(c, smps, cnt); } return cnt; } +int websocket_parse(struct node *n, config_setting_t *cfg) +{ + config_setting_t *cfg_dests; + + cfg_dests = config_setting_get_member(cfg, "destinations"); + + if (!config_setting_is_array(cfg_dests)) + cerror(dests, "The 'destinations' setting must be an array of URLs"); + + for (int i = 0; i < config_setting_length(cfg_dests); i++) { + config_setting_t *cfg_dest; + const char *url; + struct lws_client_connect_info *i; + + url = config_setting_get_string_elem(cfg_dests, i); + if (!url) + cerror(dests, "The 'destinations' setting must be an array of URLs"); + + i = alloc(sizeof()) + + } +} + +char * websocket_print(struct node *n) +{ + +} + static struct node_type vt = { .name = "websocket", .description = "Send and receive samples of a WebSocket connection (libwebsockets)", @@ -557,7 +620,9 @@ static struct node_type vt = { .read = websocket_read, .write = websocket_write, .init = websocket_init, - .deinit = websocket_deinit + .deinit = websocket_deinit, + .print = websocket_print, + .parse = websocket_parse }; REGISTER_NODE_TYPE(&vt) \ No newline at end of file diff --git a/thirdparty/libwebsockets b/thirdparty/libwebsockets index 0c984014f..5fb327754 160000 --- a/thirdparty/libwebsockets +++ b/thirdparty/libwebsockets @@ -1 +1 @@ -Subproject commit 0c984014f0a82e184af2ff18f97b45e2cbccd0bd +Subproject commit 5fb327754ab4d202fca903dd5bd6b546b340eecb From 15e7e78e04a8b5e1d96c71164600ff69863817f9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 7 Nov 2016 22:20:09 -0500 Subject: [PATCH 039/211] mark samples with source node --- include/villas/sample.h | 1 + lib/node.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/villas/sample.h b/include/villas/sample.h index 4caf3f927..53230a7cf 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -45,6 +45,7 @@ struct sample { atomic_int refcnt; /**< Reference counter. */ struct pool *pool; /**< This sample is belong to this memory pool. */ + struct node *source; /**< The node from which this sample originates. */ /** All timestamps are seconds / nano seconds after 1.1.1970 UTC */ struct { diff --git a/lib/node.c b/lib/node.c index b4aa9dc02..9bfe0a4c6 100644 --- a/lib/node.c +++ b/lib/node.c @@ -38,6 +38,9 @@ int node_read(struct node *n, struct sample *smps[], unsigned cnt) nread = n->_vt->read(n, smps, cnt); } + for (int i = 0; i < nread; i++) + smps[i]->source = n; + return nread; } From fab53b0302fda003333e5affe5609eee4168e2f6 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Nov 2016 00:24:57 -0500 Subject: [PATCH 040/211] further steps to implement websocket client functionality --- include/villas/nodes/websocket.h | 29 +--- lib/nodes/websocket.c | 269 +++++++++++++++++++------------ 2 files changed, 173 insertions(+), 125 deletions(-) diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 9d4679d51..3fb1bef79 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -19,6 +19,8 @@ #ifndef _WEBSOCKET_H_ #define _WEBSOCKET_H_ +#include + #include "node.h" #include "pool.h" #include "queue.h" @@ -28,38 +30,15 @@ struct lws; /** Internal data per websocket node */ struct websocket { - struct list connections; /**< List of active libwebsocket connections in server mode (struct websocket_connection) */ - - struct list destinations; /**< List of struct lws_client_connect_info to connect to in client mode. */ + struct list connections; /**< List of active libwebsocket connections in server mode (struct websocket_connection). */ + struct list destinations; /**< List of websocket servers connect to in client mode (struct websocket_destination). */ struct pool pool; - struct queue queue; /**< For samples which are received from WebSockets a */ int id; /**< The index of this node */ }; -struct websocket_connection { - enum { - WEBSOCKET_ESTABLISHED, - WEBSOCKET_ACTIVE, - WEBSOCKET_SHUTDOWN, - WEBSOCKET_CLOSED - } state; - - struct node *node; - struct path *path; - - struct queue queue; /**< For samples which are sent to the WebSocket */ - - struct lws *wsi; - - struct { - char name[64]; - char ip[64]; - } peer; -}; - /** @see node_vtable::init */ int websocket_init(int argc, char * argv[], config_setting_t *cfg); diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index 901d1c8ce..1809b4761 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -12,7 +12,6 @@ #include #include -#include #include #include "nodes/websocket.h" @@ -23,6 +22,35 @@ #include "cfg.h" #include "config.h" +/* Internal datastructures */ +struct connection { + enum { + WEBSOCKET_ESTABLISHED, + WEBSOCKET_ACTIVE, + WEBSOCKET_SHUTDOWN, + WEBSOCKET_CLOSED + } state; + + struct node *node; + struct path *path; + + struct queue queue; /**< For samples which are sent to the WebSocket */ + + struct lws *wsi; + + struct { + char name[64]; + char ip[64]; + } peer; + + char *_name; +}; + +struct destination { + char *uri; + struct lws_client_connect_info info; +}; + /* Private static storage */ static config_setting_t *cfg_root; /**< Root config */ static pthread_t thread; /**< All nodes are served by a single websocket server. This server is running in a dedicated thread. */ @@ -45,10 +73,93 @@ static int protocol_cb_live(struct lws *, enum lws_callback_reasons, void *, voi static struct lws_protocols protocols[] = { { "http-only", protocol_cb_http, 0, 0 }, - { "live", protocol_cb_live, sizeof(struct websocket_connection), 0 }, + { "live", protocol_cb_live, sizeof(struct connection), 0 }, { NULL } }; +__attribute__((unused)) static int connection_init(struct connection *c) +{ + /** @todo */ + return -1; +} + +__attribute__((unused)) static void connection_destroy(struct connection *c) +{ + if (c->_name) + free(c->_name); +} + +static char * connection_name(struct connection *c) +{ + if (!c->_name) { + if (c->node) + asprintf(&c->_name, "%s (%s) for node %s", c->peer.name, c->peer.ip, node_name(c->node)); + else + asprintf(&c->_name, "%s (%s) for all nodes", c->peer.name, c->peer.ip); + } + + return c->_name; +} + +static void destination_destroy(struct destination *d) +{ + free(d->uri); +} + +static int connection_write(struct connection *c, struct sample *smps[], unsigned cnt) +{ + int blocks, enqueued; + char *bufs[cnt]; + + struct websocket *w = c->node->_vd; + + switch (c->state) { + case WEBSOCKET_SHUTDOWN: + return -1; + case WEBSOCKET_CLOSED: + if (c->node) { + struct websocket *w = (struct websocket *) c->node->_vd; + list_remove(&w->connections, c); + } + else + list_remove(&connections, c); + break; + + case WEBSOCKET_ESTABLISHED: + c->state = WEBSOCKET_ACTIVE; + /* fall through */ + + case WEBSOCKET_ACTIVE: + blocks = pool_get_many(&w->pool, (void **) bufs, cnt); + if (blocks != cnt) + warn("Pool underrun in websocket connection: %s", connection_name(c)); + + for (int i = 0; i < blocks; i++) { + struct webmsg *msg = (struct webmsg *) (bufs[i] + LWS_PRE); + + msg->version = WEBMSG_VERSION; + msg->type = WEBMSG_TYPE_DATA; + msg->endian = WEBMSG_ENDIAN_HOST; + msg->length = smps[i]->length; + msg->sequence = smps[i]->sequence; + msg->id = w->id; + msg->ts.sec = smps[i]->ts.origin.tv_sec; + msg->ts.nsec = smps[i]->ts.origin.tv_nsec; + + memcpy(&msg->data, &smps[i]->data, smps[i]->length * 4); + } + + enqueued = queue_push_many(&c->queue, (void **) bufs, cnt); + if (enqueued != blocks) + warn("Queue overrun in websocket connection: %s", connection_name(c)); + + lws_callback_on_writable(c->wsi); + break; + } + + return 0; +} + static void logger(int level, const char *msg) { int len = strlen(msg); if (strchr(msg, '\n')) @@ -102,7 +213,7 @@ static char * get_mimetype(const char *resource_path) return "text/plain"; } -int protocol_cb_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +static int protocol_cb_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { switch (reason) { case LWS_CALLBACK_HTTP: @@ -220,10 +331,10 @@ try_to_reuse: return 0; } -int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +static int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { int ret; - struct websocket_connection *c = user; + struct connection *c = user; struct websocket *w; switch (reason) { @@ -268,10 +379,7 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us /* Lookup peer address for debug output */ lws_get_peer_addresses(wsi, lws_get_socket_fd(wsi), c->peer.name, sizeof(c->peer.name), c->peer.ip, sizeof(c->peer.ip)); - if (c->node != NULL) - info("LWS: New connection for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); - else - info("LWS: New connection from %s (%s)", c->peer.name, c->peer.ip); + info("LWS: New connection %s", connection_name(c)); if (c->node != NULL) { struct websocket *w = (struct websocket *) c->node->_vd; @@ -285,10 +393,7 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us } case LWS_CALLBACK_CLOSED: - if (c->node != NULL) - info("LWS: Connection closed for node %s from %s (%s)", node_name(c->node), c->peer.name, c->peer.ip); - else - info("LWS: Connection closed from %s (%s)", c->peer.name, c->peer.ip); + info("LWS: Connection %s closed", connection_name(c)); c->state = WEBSOCKET_CLOSED; c->wsi = NULL; @@ -304,7 +409,7 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us if (c->node && c->node->state != NODE_RUNNING) return -1; - if (w->state == WEBSOCKET_SHUTDOWN) { + if (c->state == WEBSOCKET_SHUTDOWN) { lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, (unsigned char *) "Node stopped", 4); return -1; } @@ -338,14 +443,14 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us return -1; if (!lws_frame_is_binary(wsi) || len < WEBMSG_LEN(0)) - warn("LWS: Received invalid packet for node: %s", node_name(c->node)); + warn("LWS: Received invalid packet for connection %s", connection_name(c)); struct webmsg *msg = (struct webmsg *) in; while ((char *) msg + WEBMSG_LEN(msg->length) <= (char *) in + len) { struct webmsg *msg2 = pool_get(&w->pool); if (!msg2) { - warn("Pool underrun for node: %s", node_name(c->node)); + warn("Pool underrun for connection %s", connection_name(c)); break; } @@ -353,7 +458,7 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us ret = queue_push(&w->queue, msg2); if (ret != 1) { - warn("Queue overrun for node: %s", node_name(c->node)); + warn("Queue overrun for connection %s", connection_name(c)); break; } @@ -451,7 +556,7 @@ int websocket_close(struct node *n) { struct websocket *w = n->_vd; - list_foreach(struct websocket_connection *c, &w->connections) { + list_foreach(struct connection *c, &w->connections) { c->state = WEBSOCKET_SHUTDOWN; lws_callback_on_writable(c->wsi); } @@ -466,7 +571,9 @@ int websocket_close(struct node *n) int websocket_destroy(struct node *n) { -// struct websocket *w = n->_vd; + struct websocket *w = n->_vd; + + list_destroy(&w->destinations, (dtor_cb_t) destination_destroy, true); return 0; } @@ -497,85 +604,16 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt) return got; } -static int websocket_connection_init(struct websocket_connection *c) -{ - /** @todo */ - return -1; -} - -static void websocket_connection_destroy(struct websocket_connection *c) -{ - /** @todo */ -} - -static char * websocket_connection_name(struct websocket_connection *c) -{ - /** @todo */ - return "(todo)"; -} - -static int websocket_connection_write(struct websocket_connection *c, struct sample *smps[], unsigned cnt) -{ - int blocks, enqueued; - char *bufs[cnt]; - - switch (c->state) { - case WEBSOCKET_SHUTDOWN: - return -1; - case WEBSOCKET_CLOSED: - if (c->node) { - struct websocket *w = (struct websocket *) c->node->_vd; - list_remove(&w->connections, c); - } - else - list_remove(&connections, c); - break; - - case WEBSOCKET_ESTABLISHED: - c->state = WEBSOCKET_ACTIVE; - /* fall through */ - - case WEBSOCKET_ACTIVE: - blocks = pool_get_many(&w->pool, (void **) bufs, cnt); - if (blocks != cnt) - warn("Pool underrun in websocket connection: %s", websocket_connection_name(c)); - - for (int i = 0; i < blocks; i++) { - struct webmsg *msg = (struct webmsg *) (bufs[i] + LWS_PRE); - - msg->version = WEBMSG_VERSION; - msg->type = WEBMSG_TYPE_DATA; - msg->endian = WEBMSG_ENDIAN_HOST; - msg->length = smps[i]->length; - msg->sequence = smps[i]->sequence; - msg->id = w->id; - msg->ts.sec = smps[i]->ts.origin.tv_sec; - msg->ts.nsec = smps[i]->ts.origin.tv_nsec; - - memcpy(&msg->data, &smps[i]->data, smps[i]->length * 4); - } - - enqueued = queue_push_many(&c->queue, (void **) bufs, cnt); - if (enqueued != blocks) - warn("Queue overrun in websocket connection: %s", websocket_connection_name(c)); - - lws_callback_on_writable(c->wsi); - break; - } - - return 0; -} - int websocket_write(struct node *n, struct sample *smps[], unsigned cnt) { struct websocket *w = n->_vd; - list_foreach(struct websocket_connection *c, &w->connections) { - websocket_write_connection(c, smps, cnt); + list_foreach(struct connection *c, &w->connections) { + connection_write(c, smps, cnt); } - list_foreach(struct websocket_connection *c, &connections) { - websocket_write_connection(c, smps, cnt); + list_foreach(struct connection *c, &connections) { + connection_write(c, smps, cnt); } return cnt; @@ -583,30 +621,61 @@ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt) int websocket_parse(struct node *n, config_setting_t *cfg) { + struct websocket *w = n->_vd; config_setting_t *cfg_dests; + int ret; cfg_dests = config_setting_get_member(cfg, "destinations"); if (!config_setting_is_array(cfg_dests)) - cerror(dests, "The 'destinations' setting must be an array of URLs"); + cerror(cfg_dests, "The 'destinations' setting must be an array of URLs"); for (int i = 0; i < config_setting_length(cfg_dests); i++) { - config_setting_t *cfg_dest; - const char *url; - struct lws_client_connect_info *i; + struct destination *d; + const char *uri, *prot, *ads, *path; - url = config_setting_get_string_elem(cfg_dests, i); - if (!url) - cerror(dests, "The 'destinations' setting must be an array of URLs"); + uri = config_setting_get_string_elem(cfg_dests, i); + if (!uri) + cerror(cfg_dests, "The 'destinations' setting must be an array of URLs"); - i = alloc(sizeof()) + d = alloc(sizeof(struct destination)); + d->uri = strdup(uri); + if (!d->uri) + serror("Failed to allocate memory"); + + ret = lws_parse_uri(d->uri, &prot, &ads, &d->info.port, &path); + if (ret) + cerror(cfg_dests, "Failed to parse websocket URI: '%s'", uri); + + d->info.ssl_connection = !strcmp(prot, "https"); + d->info.address = ads; + d->info.path = path; + d->info.protocol = prot; + d->info.ietf_version_or_minus_one = -1; + + list_push(&w->destinations, d); } + + return 0; } char * websocket_print(struct node *n) { + struct websocket *w = n->_vd; + + char *buf = NULL; + list_foreach(struct lws_client_connect_info *in, &w->destinations) { + buf = strcatf(&buf, "%s://%s:%d/%s", + in->ssl_connection ? "https" : "http", + in->address, + in->port, + in->path + ); + } + + return buf; } static struct node_type vt = { From 1d3bb7c730624e911a20164ff8e8ebf5cd119c21 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Nov 2016 00:26:06 -0500 Subject: [PATCH 041/211] some cleanups in the hook system --- include/villas/hooks.h | 5 +---- lib/hooks/hooks-internal.c | 15 +++------------ lib/path.c | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 110e01ba6..f87f228d1 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -103,7 +103,7 @@ enum hook_type { HOOK_INIT = 1 << 9, /**< Called before path is started to parseHOOK_DESTROYs. */ HOOK_DESTROY = 1 << 10, /**< Called after path has been stopped to release memory allocated by HOOK_INIT */ - HOOK_INTERNAL = 1 << 11, /**< Internal hooks are added to every path implicitely. */ + HOOK_AUTO = 1 << 11, /**< Internal hooks are added to every path implicitely. */ HOOK_PARSE = 1 << 12, /**< Called for parsing hook arguments. */ /** @{ Classes of hooks */ @@ -113,9 +113,6 @@ enum hook_type { HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART, /** Hooks which are used to collect statistics. */ HOOK_STATS = HOOK_INTERNAL | HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, - - /** All hooks */ - HOOK_ALL = HOOK_INTERNAL - 1 /** @} */ }; diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index cb91505fd..5ce5cf705 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -12,14 +12,11 @@ #include "path.h" #include "utils.h" -REGISTER_HOOK("fix_ts", "Update timestamps of sample if not set", 0, 0, hook_fix_ts, HOOK_INTERNAL | HOOK_READ) +REGISTER_HOOK("fix_ts", "Update timestamps of sample if not set", 0, 0, hook_fix_ts, HOOK_AUTO | HOOK_READ) int hook_fix_ts(struct hook *h, int when, struct hook_info *j) { struct timespec now = time_now(); - if (when != HOOK_READ) - return 0; - assert(j->smps); for (int i = 0; i < j->cnt; i++) { @@ -41,12 +38,9 @@ int hook_fix_ts(struct hook *h, int when, struct hook_info *j) return j->cnt; } -REGISTER_HOOK("restart", "Call restart hooks for current path", 1, 1, hook_restart, HOOK_INTERNAL | HOOK_READ) +REGISTER_HOOK("restart", "Call restart hooks for current path", 1, 1, hook_restart, HOOK_AUTO | HOOK_READ) int hook_restart(struct hook *h, int when, struct hook_info *j) { - if (when != HOOK_READ) - return 0; - assert(j->smps); assert(j->path); @@ -69,14 +63,11 @@ int hook_restart(struct hook *h, int when, struct hook_info *j) return j->cnt; } -REGISTER_HOOK("drop", "Drop messages with reordered sequence numbers", 3, 1, hook_drop, HOOK_INTERNAL | HOOK_READ) +REGISTER_HOOK("drop", "Drop messages with reordered sequence numbers", 3, 1, hook_drop, HOOK_AUTO | HOOK_READ) int hook_drop(struct hook *h, int when, struct hook_info *j) { int i, ok, dist; - if (when != HOOK_READ) - return 0; - assert(j->smps); for (i = 0, ok = 0; i < j->cnt; i++) { diff --git a/lib/path.c b/lib/path.c index 4a9045072..18ab94b53 100644 --- a/lib/path.c +++ b/lib/path.c @@ -171,7 +171,7 @@ int path_init(struct path *p) /* Add internal hooks if they are not already in the list*/ list_foreach(struct hook *h, &hooks) { if ( - (h->type & HOOK_INTERNAL) && /* is internal hook? */ + (h->type & HOOK_AUTO) && /* should this hook be added implicitely? */ (list_lookup(&p->hooks, h->name) == NULL) /* is not already in list? */ ) list_push(&p->hooks, memdup(h, sizeof(struct hook))); From baaa809b90caaa908fc0076a4b5e8e06a1eed2cc Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Nov 2016 00:26:56 -0500 Subject: [PATCH 042/211] remove STATS_INVALID as it is too specific for the socket node-type --- include/villas/stats.h | 1 - lib/stats.c | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/villas/stats.h b/include/villas/stats.h index 49d6e11ef..f5c4178c5 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -24,7 +24,6 @@ struct path; struct node; enum stats_id { - STATS_INVALID, /**< Counter for invalid messages */ STATS_SKIPPED, /**< Counter for skipped messages due to hooks */ STATS_DROPPED, /**< Counter for dropped messages due to reordering */ STATS_GAP_SEQUENCE, /**< Histogram of sequence number displacement of received messages */ diff --git a/lib/stats.c b/lib/stats.c index 5bcceee21..e62dda812 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -23,7 +23,6 @@ static struct stats_desc { double resolution; } hist; } stats_table[] = { - { "invalid", "", "invalid messages", {0, 0, -1, }}, { "skipped", "", "skipped messages by hooks", {0, 0, -1, }}, { "dropped", "", "dropped messages because of reordering", {0, 0, -1, }}, { "gap_sequence", "", "sequence number displacement of received messages", {-10, 10, 20, }}, @@ -127,24 +126,22 @@ void stats_print_header() { #define UNIT(u) "(" YEL(u) ")" - stats("%-40s|%19s|%19s|%19s|%19s|%19s|", "Source " MAG("=>") " Destination", + stats("%-40s|%19s|%19s|%19s|%19s|", "Source " MAG("=>") " Destination", "OWD" UNIT("S") " ", "Rate" UNIT("p/S") " ", "Drop" UNIT("p") " ", - "Skip" UNIT("p") " ", - "Inval" UNIT("p") " " + "Skip" UNIT("p") " " ); line(); } void stats_print_periodic(struct stats *s, struct path *p) { - stats("%-40.40s|%10f|%10f|%10ju|%10ju|%10ju|", path_name(p), + stats("%-40.40s|%10f|%10f|%10ju|%10ju|", path_name(p), s->histograms[STATS_OWD].last, 1.0 / s->histograms[STATS_GAP_SAMPLE].last, s->histograms[STATS_DROPPED].total, - s->histograms[STATS_SKIPPED].total, - s->histograms[STATS_INVALID].total + s->histograms[STATS_SKIPPED].total ); } From f50e44937348491d51bd6603fcd9dd1244196e62 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Nov 2016 00:27:28 -0500 Subject: [PATCH 043/211] refactoring in the stats system to fix some compiler errors --- include/villas/hooks.h | 2 +- include/villas/path.h | 2 +- include/villas/stats.h | 12 ++++---- lib/hooks/hooks-internal.c | 3 +- lib/hooks/hooks-stats.c | 3 +- lib/stats.c | 56 +++++++++++++++----------------------- 6 files changed, 34 insertions(+), 44 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index f87f228d1..f88635a21 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -112,7 +112,7 @@ enum hook_type { /** All path related actions */ HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART, /** Hooks which are used to collect statistics. */ - HOOK_STATS = HOOK_INTERNAL | HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, + HOOK_STATS = HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, /** @} */ }; diff --git a/include/villas/path.h b/include/villas/path.h index 7bf71a003..c9e5104aa 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -67,7 +67,7 @@ struct path char *_name; /**< Singleton: A string which is used to print this path to screen. */ - struct stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ + struct stats_delta *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ }; diff --git a/include/villas/stats.h b/include/villas/stats.h index f5c4178c5..dc69beb41 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -34,7 +34,9 @@ enum stats_id { }; struct stats_delta { - double vals[STATS_COUNT]; + double values[STATS_COUNT]; + + struct sample *last; }; struct stats { @@ -47,14 +49,12 @@ int stats_init(struct stats *s); void stats_destroy(struct stats *s); -void stats_update(struct stats *s, enum stats_id id, double val); +void stats_update(struct stats_delta *s, enum stats_id id, double val); + +void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt); int stats_commit(struct stats *s, struct stats_delta *d); -void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); - -void stats_decollect(struct stats *s, struct sample *smps[], size_t cnt); - #ifdef WITH_JANSSON json_t * stats_json(struct stats *s); #endif diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 5ce5cf705..81673a3c3 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -76,8 +76,9 @@ int hook_drop(struct hook *h, int when, struct hook_info *j) if (h->prev) { dist = h->last->sequence - (int32_t) h->prev->sequence; if (dist <= 0) { - stats_update(j->path->stats, STATS_DROPPED, dist); warn("Dropped sample: dist = %d, i = %d", dist, i); + if (j->path) + stats_update(j->path->stats, STATS_DROPPED, dist); } else { struct sample *tmp; diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index e0139efff..f9fb97b7f 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -22,8 +22,9 @@ int hook_stats(struct hook *h, int when, struct hook_info *j) switch (when) { case HOOK_READ: assert(j->smps); + assert(j->path); - stats_collect(s, j->smps, j->cnt); + stats_collect(j->path->stats, j->smps, j->cnt); break; case HOOK_PATH_STOP: diff --git a/lib/stats.c b/lib/stats.c index e62dda812..6441edf85 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -48,54 +48,42 @@ void stats_destroy(struct stats *s) } } -void stats_update(struct stats *s, enum stats_id id, double val) +void stats_update(struct stats_delta *d, enum stats_id id, double val) { - if (!s) - return; - - hist_put(&s->histograms[id], val); + if (d && id >= 0 && id < STATS_COUNT) + d->values[id] = val; } -#if 0 -int stats_delta(struct stats_delta *d, struct sample *s, struct sample *p) -{ - d->histogram.owd = time_delta(&smps[i]->ts.origin, &smps[i]->ts.received); - d->histogram.gap = time_delta(&s->last->ts.origin, &smps[i]->ts.origin); - d->histogram.gap_seq = s->sequence - (int32_t) p->sequence; - d->histogram.gap_recv = time_delta(&s->last->ts.received, &smps[i]->ts.received); - - d->counter.dropped = d->histogram.gap_seq <= 0 ? 1 : 0; - d->counter.invalid = 0; - - return 0; -} -#endif - int stats_commit(struct stats *s, struct stats_delta *d) { for (int i = 0; i < STATS_COUNT; i++) { - hist_put(&s->histograms[i], d->vals[i]); + hist_put(&s->histograms[i], d->values[i]); } return 0; } -void stats_collect(struct stats *s, struct sample *smps[], size_t cnt) +void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt) { - for (int i = 0; i < cnt; i++) { - if (s->last) { -// struct stats_delta d; -// stats_get_delta(&d, smps[i], s->last); -// stats_commit(s, &d); + struct sample *previous = s->last; + + if (previous) { + sample_put(previous); + + for (int i = 0; i < cnt; i++) { + stats_update(s, STATS_GAP_RECEIVED, time_delta(&previous->ts.received, &smps[i]->ts.received)); + stats_update(s, STATS_GAP_SAMPLE, time_delta(&previous->ts.origin, &smps[i]->ts.origin)); + stats_update(s, STATS_OWD, time_delta(&smps[i]->ts.origin, &smps[i]->ts.received)); + stats_update(s, STATS_GAP_SEQUENCE, smps[i]->sequence - (int32_t) previous->sequence); + + /* Make sure there is always a reference to the previous sample */ + + previous = smps[i]; } - - if (i == 0 && s->last) - sample_put(s->last); - if (i == cnt - 1) - sample_get(smps[i]); - - s->last = smps[i]; } + + sample_get(previous); + s->last = previous; } #ifdef WITH_JANSSON From 90e973ce37e5b4bfbf57cd354ea095c0cf75269d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Nov 2016 00:36:04 -0500 Subject: [PATCH 044/211] fix memory allocation bug discovered by CI :-) --- include/villas/hist.h | 3 ++- lib/hist.c | 6 ++++-- tests/hist.c | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/villas/hist.h b/include/villas/hist.h index abb3ea091..9779ffef6 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -11,6 +11,7 @@ #define _HIST_H_ #include +#include #include "config.h" @@ -46,7 +47,7 @@ struct hist { }; /** Initialize struct hist with supplied values and allocate memory for buckets. */ -void hist_create(struct hist *h, double start, double end, double resolution); +int hist_create(struct hist *h, double start, double end, double resolution); /** Free the dynamically allocated memory. */ void hist_destroy(struct hist *h); diff --git a/lib/hist.c b/lib/hist.c index 21baa6784..2cda30811 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -19,7 +19,7 @@ #define VAL(h, i) ((h)->low + (i) * (h)->resolution) #define INDEX(h, v) round((v - (h)->low) / (h)->resolution) -void hist_create(struct hist *h, double low, double high, double resolution) +int hist_create(struct hist *h, double low, double high, double resolution) { h->low = low; h->high = high; @@ -27,7 +27,7 @@ void hist_create(struct hist *h, double low, double high, double resolution) if (resolution > 0) { h->length = (high - low) / resolution; - h->data = alloc(h->length * sizeof(unsigned)); + h->data = alloc(h->length * sizeof(hist_cnt_t)); } else { h->length = 0; @@ -35,6 +35,8 @@ void hist_create(struct hist *h, double low, double high, double resolution) } hist_reset(h); + + return 0; } void hist_destroy(struct hist *h) diff --git a/tests/hist.c b/tests/hist.c index df9c655e8..aeca35701 100644 --- a/tests/hist.c +++ b/tests/hist.c @@ -18,8 +18,10 @@ const int hist_result[] = {}; Test(hist, simple) { struct hist h; + int ret; - hist_create(&h, -100, 100, 1); + ret = hist_create(&h, -100, 100, 1); + cr_assert_eq(ret, 0); for (int i = 0; i < ARRAY_LEN(test_data); i++) hist_put(&h, test_data[i]); From 4bb0aa76c9b25a3a3723e9dde94ab7f118a177e7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 02:45:16 -0500 Subject: [PATCH 045/211] increase number of reserved huge pages automatically if required --- config.h | 4 ++++ include/villas/kernel/kernel.h | 10 +++++++++- include/villas/memory.h | 3 +++ lib/kernel/kernel.c | 32 ++++++++++++++++++++++++++++++++ lib/memory.c | 15 +++++++++++++++ src/node.c | 4 ++++ src/pipe.c | 3 +++ src/test.c | 3 +++ tests/Makefile.inc | 1 - 9 files changed, 73 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index 087f7b3f9..f40f333a9 100644 --- a/config.h +++ b/config.h @@ -24,6 +24,10 @@ #define DEFAULT_VALUES 64 #define DEFAULT_QUEUELEN 1024 +/** Number of hugepages which are requested from the the kernel. + * @see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt */ +#define DEFAULT_NR_HUGEPAGES 25 + /** Width of log output in characters */ #define LOG_WIDTH 132 diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index 10e750468..300866e1c 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -12,6 +12,8 @@ #include +#include "config.h" + //#include /** Check if current process has capability \p cap. @@ -19,7 +21,13 @@ * @retval 0 If capabilty is present. * @retval <0 If capability is not present. */ -//int kernel_check_cap(cap_value_t cap): +//int kernel_check_cap(cap_value_t cap); + +/** Get number of reserved hugepages. */ +int kernel_get_nr_hugepages(); + +/** Set number of reserved hugepages. */ +int kernel_set_nr_hugepages(int nr); /** Checks for realtime (PREEMPT_RT) patched kernel. * diff --git a/include/villas/memory.h b/include/villas/memory.h index f6e3064f5..e546c106b 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -44,6 +44,9 @@ struct memzone { size_t len; }; +/** Initilialize memory subsystem */ +int memory_init(); + /** Allocate \p len bytes memory of type \p m. * * @retval NULL If allocation failed. diff --git a/lib/kernel/kernel.c b/lib/kernel/kernel.c index b2c9b94cc..00a0818e7 100644 --- a/lib/kernel/kernel.c +++ b/lib/kernel/kernel.c @@ -152,6 +152,38 @@ int kernel_get_cacheline_size() return sysconf(_SC_LEVEL1_ICACHE_LINESIZE); } +int kernel_get_nr_hugepages() +{ + FILE *f; + int nr, ret; + + f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "r"); + if (!f) + serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages"); + + ret = fscanf(f, "%d", &nr); + if (ret != 1) + nr = -1; + + fclose(f); + + return nr; +} + +int kernel_set_nr_hugepages(int nr) +{ + FILE *f; + + f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w"); + if (!f) + serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages"); + + fprintf(f, "%d\n", nr); + fclose(f); + + return 0; +} + #if 0 int kernel_check_cap(cap_value_t cap) { diff --git a/lib/memory.c b/lib/memory.c index 2f46161b3..2e3120450 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -12,11 +12,26 @@ /* Required to allocate hugepages on Apple OS X */ #ifdef __MACH__ #include +#elif defined(__linux__) + #include "kernel/kernel.h" #endif #include "log.h" #include "memory.h" +int memory_init() +{ +#ifdef __linux__ + int nr = kernel_get_nr_hugepages(); + + debug(DBG_MEM | 2, "System has %d reserved hugepages", nr); + + if (nr < DEFAULT_NR_HUGEPAGES) + kernel_set_nr_hugepages(DEFAULT_NR_HUGEPAGES); +#endif + return 0; +} + void * memory_alloc(const struct memtype *m, size_t len) { debug(DBG_MEM | 2, "Allocating %#zx bytes of %s memory", len, m->name); diff --git a/src/node.c b/src/node.c index 93c42b1fc..a578f507a 100644 --- a/src/node.c +++ b/src/node.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -124,6 +125,9 @@ int main(int argc, char *argv[]) info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); + + info("Initialize memory system"); + memory_init(); info("Initialize signals"); signals_init(); diff --git a/src/pipe.c b/src/pipe.c index 2226c917d..16c4e0a35 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -225,6 +225,9 @@ int main(int argc, char *argv[]) info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); + info("Initialize memory system"); + memory_init(); + /* Initialize node */ node = list_lookup(&nodes, argv[2]); if (!node) diff --git a/src/test.c b/src/test.c index bb31796d0..18d8e8eef 100644 --- a/src/test.c +++ b/src/test.c @@ -87,6 +87,9 @@ int main(int argc, char *argv[]) log_init(); cfg_parse(argv[1], &config, &settings, &nodes, NULL); + info("Initialize memory system"); + memory_init(); + node = list_lookup(&nodes, argv[3]); if (!node) error("There's no node with the name '%s'", argv[3]); diff --git a/tests/Makefile.inc b/tests/Makefile.inc index 9bac51525..277851453 100644 --- a/tests/Makefile.inc +++ b/tests/Makefile.inc @@ -8,7 +8,6 @@ TEST_LDLIBS = $(LDLIBS) -lcriterion -lvillas -pthread tests: $(BUILDDIR)/testsuite run-tests: tests - echo 25 > /proc/sys/vm/nr_hugepages $(BUILDDIR)/testsuite # Compile From eda6c66f0eaa9547f80cc3af920897914b34484b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 02:45:39 -0500 Subject: [PATCH 046/211] use proper style for #include --- src/hook.c | 3 ++- src/node.c | 6 +++--- src/signal.c | 7 ++++--- src/test.c | 20 +++++++++++++------- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/hook.c b/src/hook.c index 7b04cd27e..d30133410 100644 --- a/src/hook.c +++ b/src/hook.c @@ -18,7 +18,8 @@ #include #include #include -#include + +#include "config.h" static void usage() { diff --git a/src/node.c b/src/node.c index a578f507a..4b8d9f681 100644 --- a/src/node.c +++ b/src/node.c @@ -12,8 +12,6 @@ #include #include -#include "config.h" - #include #include #include @@ -23,9 +21,11 @@ #include #ifdef ENABLE_OPAL_ASYNC - #include "opal.h" + #include #endif +#include "config.h" + struct list paths; /**< List of paths */ struct list nodes; /**< List of nodes */ diff --git a/src/signal.c b/src/signal.c index 2d47dfa95..601c350d3 100644 --- a/src/signal.c +++ b/src/signal.c @@ -14,10 +14,11 @@ #include #include +#include +#include +#include + #include "config.h" -#include "utils.h" -#include "sample.h" -#include "timing.h" #define CLOCKID CLOCK_REALTIME diff --git a/src/test.c b/src/test.c index 18d8e8eef..8e4f56ae6 100644 --- a/src/test.c +++ b/src/test.c @@ -13,14 +13,15 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + #include "config.h" -#include "cfg.h" -#include "msg.h" -#include "node.h" -#include "utils.h" -#include "hist.h" -#include "timing.h" -#include "pool.h" struct settings settings; /** Date: Sun, 20 Nov 2016 02:50:12 -0500 Subject: [PATCH 047/211] fix: initialize hooks only if required --- lib/hooks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/hooks.c b/lib/hooks.c index daad04c42..5eb56c7ee 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -27,7 +27,10 @@ int hook_init(struct hook *h, struct list *nodes, struct list *paths, struct set .settings = settings }; - return h->cb(h, HOOK_INIT, &i); + if (h->type & HOOK_INIT) + return h->cb(h, HOOK_INIT, &i); + else + return 0; } void hook_destroy(struct hook *h) From b8a8476a923c022c6be2b66fdddf2207fabf7bca Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 02:50:49 -0500 Subject: [PATCH 048/211] add custom main() for criterion tests in order to initiatize huge pages --- tests/main.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/main.c diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 000000000..370ba501f --- /dev/null +++ b/tests/main.c @@ -0,0 +1,26 @@ +/** Custom main() for Criterion + * + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include + +#include +#include + +int main(int argc, char *argv[]) { + struct criterion_test_set *tests = criterion_initialize(); + + info("Initialize memory system"); + memory_init(); + + int result = 0; + if (criterion_handle_args(argc, argv, true)) + result = !criterion_run_all_tests(tests); + + criterion_finalize(tests); + return result; +} \ No newline at end of file From bfec0b2f0091d72e800f2a64342f53868ce76ed3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 03:02:19 -0500 Subject: [PATCH 049/211] added missing implementation for aligned memory allocator --- include/villas/memory.h | 2 +- lib/memory.c | 29 +++++++++++++++++++++-------- tests/memory.c | 5 ++--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/villas/memory.h b/include/villas/memory.h index e546c106b..0390a0b92 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -15,7 +15,7 @@ #define HUGEPAGESIZE (1 << 21) -typedef void *(*memzone_allocator_t)(size_t len); +typedef void *(*memzone_allocator_t)(size_t len, size_t alignment); typedef int (*memzone_deallocator_t)(void *ptr, size_t len); enum memtype_flags { diff --git a/lib/memory.c b/lib/memory.c index 2e3120450..85ef52d7f 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -34,15 +34,20 @@ int memory_init() void * memory_alloc(const struct memtype *m, size_t len) { - debug(DBG_MEM | 2, "Allocating %#zx bytes of %s memory", len, m->name); - return m->alloc(len); + void *ptr = m->alloc(len, sizeof(void *)); + + debug(DBG_MEM | 2, "Allocated %#zx bytes of %s memory: %p", len, m->name, ptr); + + return ptr; } void * memory_alloc_aligned(const struct memtype *m, size_t len, size_t alignment) { - debug(DBG_MEM | 2, "Allocating %#zx bytes of %#zx-byte-aligned %s memory", len, alignment, m->name); - warn("%s: not implemented yet!", __FUNCTION__); - return memory_alloc(m, len); + void *ptr = m->alloc(len, alignment); + + debug(DBG_MEM | 2, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", len, alignment, m->name, ptr); + + return ptr; } int memory_free(const struct memtype *m, void *ptr, size_t len) @@ -51,9 +56,17 @@ int memory_free(const struct memtype *m, void *ptr, size_t len) return m->free(ptr, len); } -static void * memory_heap_alloc(size_t len) +static void * memory_heap_alloc(size_t len, size_t alignment) { - return malloc(len); + void *ptr; + int ret; + + if (alignment < sizeof(void *)) + alignment = sizeof(void *); + + ret = posix_memalign(&ptr, alignment, len); + + return ret ? NULL : ptr; } int memory_heap_free(void *ptr, size_t len) @@ -64,7 +77,7 @@ int memory_heap_free(void *ptr, size_t len) } /** Allocate memory backed by hugepages with malloc() like interface */ -static void * memory_hugepage_alloc(size_t len) +static void * memory_hugepage_alloc(size_t len, size_t alignment) { int prot = PROT_READ | PROT_WRITE; int flags = MAP_PRIVATE | MAP_ANONYMOUS; diff --git a/tests/memory.c b/tests/memory.c index 234e6defd..6c56d1be8 100644 --- a/tests/memory.c +++ b/tests/memory.c @@ -15,8 +15,7 @@ #include "utils.h" TheoryDataPoints(memory, aligned) = { -// DataPoints(size_t, 1, 32, 55, 1 << 10, 1 << 20), - DataPoints(size_t, 1<<12), + DataPoints(size_t, 1, 32, 55, 1 << 10, 1 << 20), DataPoints(size_t, 1, 8, 1 << 12), DataPoints(const struct memtype *, &memtype_heap, &memtype_hugepage) }; @@ -28,7 +27,7 @@ Theory((size_t len, size_t align, const struct memtype *m), memory, aligned) { ptr = memory_alloc_aligned(m, len, align); cr_assert_neq(ptr, NULL, "Failed to allocate memory"); - //cr_assert(IS_ALIGNED(ptr, align)); + cr_assert(IS_ALIGNED(ptr, align)); if (m == &memtype_hugepage) { cr_assert(IS_ALIGNED(ptr, HUGEPAGESIZE)); From b9d5bccb570eee82199bc9befa1be70bed98b5bd Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 03:40:23 -0500 Subject: [PATCH 050/211] improved debug outputs for paths --- lib/path.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/path.c b/lib/path.c index 18ab94b53..271de36e2 100644 --- a/lib/path.c +++ b/lib/path.c @@ -62,7 +62,7 @@ static void path_read(struct path *p) for (int i = 0; i < enqueued; i++) sample_get(smps[i]); /* increase reference count */ - debug(DBG_PATH | 15, "Enqueued %u samples to queue of path %s", enqueued, path_name(p)); + debug(DBG_PATH | 15, "Enqueued %u samples from %s to queue of %s", enqueued, node_name(ps->node), node_name(pd->node)); } } @@ -154,11 +154,22 @@ int path_stop(struct path *p) const char * path_name(struct path *p) { - if (!p->_name) { - strcatf(&p->_name, "%s " MAG("=>"), node_name_short(p->source->node)); - - list_foreach(struct path_destination *pd, &p->destinations) - strcatf(&p->_name, " %s", node_name_short(pd->node)); + if (!p->_name) { + if (list_length(&p->destinations) == 1) { + struct path_destination *pd = (struct path_destination *) list_first(&p->destinations); + + strcatf(&p->_name, "%s " MAG("=>") " %s", + node_name_short(p->source->node), + node_name_short(pd->node)); + } + else { + strcatf(&p->_name, "%s " MAG("=>") " [", node_name_short(p->source->node)); + + list_foreach(struct path_destination *pd, &p->destinations) + strcatf(&p->_name, " %s", node_name_short(pd->node)); + + strcatf(&p->_name, " ]"); + } } return p->_name; From 8240bf52c96ffb865d22aa3f8a144d958ed33b1d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 03:44:51 -0500 Subject: [PATCH 051/211] fixed debug output: incorrect number of released samples --- lib/path.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/path.c b/lib/path.c index 271de36e2..e5c7728b9 100644 --- a/lib/path.c +++ b/lib/path.c @@ -100,8 +100,10 @@ static void path_write(struct path *p) debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(pd->node)); released = 0; - for (int i = 0; i < sent; i++) - released += sample_put(smps[i]); + for (int i = 0; i < sent; i++) { + if (sample_put(smps[i]) == 0) + released++; /* we had the last reference (0 remaining) */ + } debug(DBG_PATH | 15, "Released %d samples back to memory pool", released); } From 671e964d4309f6db1ecc592986a98133873a1404 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 03:46:53 -0500 Subject: [PATCH 052/211] only call HOOK_DESTROY callback if hook supports it --- lib/hooks.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/hooks.c b/lib/hooks.c index 5eb56c7ee..15492a52d 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -36,7 +36,9 @@ int hook_init(struct hook *h, struct list *nodes, struct list *paths, struct set void hook_destroy(struct hook *h) { struct hook_info i = { NULL }; - h->cb(h, HOOK_DESTROY, &i); + + if (h->type & HOOK_DESTROY) + h->cb(h, HOOK_DESTROY, &i); } int hook_copy(struct hook *h, struct hook *c) From cbaf8d40b3f3939d2bc5495261ea1db1e840cd01 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 03:47:41 -0500 Subject: [PATCH 053/211] remove HOOK_STATS as it is only used once in the codebase --- include/villas/hooks.h | 4 +--- lib/hooks/hooks-stats.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index f88635a21..66501985b 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -110,9 +110,7 @@ enum hook_type { /** Hooks which are using private data must allocate and free them propery. */ HOOK_STORAGE = HOOK_INIT | HOOK_DESTROY, /** All path related actions */ - HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART, - /** Hooks which are used to collect statistics. */ - HOOK_STATS = HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC, + HOOK_PATH = HOOK_PATH_START | HOOK_PATH_STOP | HOOK_PATH_RESTART /** @} */ }; diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index f9fb97b7f..bd78d3c87 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -14,7 +14,7 @@ extern struct list *hook_nodes; -REGISTER_HOOK("stats", "Collect statistics for the current path", 2, 1, hook_stats, HOOK_STATS) +REGISTER_HOOK("stats", "Collect statistics for the current path", 2, 1, hook_stats, HOOK_STORAGE | HOOK_PATH | HOOK_READ | HOOK_PERIODIC) int hook_stats(struct hook *h, int when, struct hook_info *j) { struct stats *s = hook_storage(h, when, sizeof(struct stats), (ctor_cb_t) stats_init, (dtor_cb_t) stats_destroy); From b37d3df332014b0f3c7169db359656b43a66a2e8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 12:59:37 -0500 Subject: [PATCH 054/211] moved cfg_parse_{hook, node, path} to {hooks, node, path}.c --- config.h | 7 +- etc/global.conf | 21 ++- include/villas/cfg.h | 60 ------- include/villas/hooks.h | 18 ++ include/villas/log.h | 17 +- include/villas/node.h | 31 +++- include/villas/path.h | 20 ++- lib/cfg.c | 400 +++++++++++++---------------------------- lib/hooks.c | 50 ++++++ lib/log.c | 48 ++++- lib/node.c | 103 ++++++++++- lib/path.c | 86 +++++++++ src/fpga.c | 7 +- src/hook.c | 7 +- src/node.c | 4 +- src/pipe.c | 8 +- src/signal.c | 4 +- src/test.c | 5 +- 18 files changed, 507 insertions(+), 389 deletions(-) diff --git a/config.h b/config.h index f40f333a9..3f4203fae 100644 --- a/config.h +++ b/config.h @@ -69,8 +69,13 @@ struct settings { int priority; /**< Process priority (lower is better) */ int affinity; /**< Process affinity of the server and all created threads */ - int debug; /**< Debug log level */ double stats; /**< Interval for path statistics. Set to 0 to disable themo disable them. */ + + struct { + int level; /**< Log level */ + int facilities; /**< Debug facilities */ + const char *file; /**< Log file */ + } log; }; #endif /* _CONFIG_H_ */ diff --git a/etc/global.conf b/etc/global.conf index 17d51c86f..fb81612fc 100644 --- a/etc/global.conf +++ b/etc/global.conf @@ -1,9 +1,5 @@ # Global configuration file for VILLASnode # -# This example includes all valid configuration options for the server. -# Please note, that using all options at the same time does not really -# makes sense. The purpose of this example is to serve as a reference. -# # The syntax of this file is similar to JSON. # A detailed description of the format can be found here: # http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files @@ -17,22 +13,31 @@ affinity = 0x01; # Mask of cores the server should run on # This also maps the NIC interrupts to those cores! -#priority = 50; # Priority for the server tasks. +priority = 50; # Priority for the server tasks. # Usually the server is using a real-time FIFO # scheduling algorithm # See: https://github.com/docker/docker/issues/22380 # on why we cant use real-time scheduling in Docker -debug = 5; # The level of verbosity for debug messages - # Higher number => increased verbosity - stats = 3; # The interval in seconds to print path statistics. # A value of 0 disables the statistics. name = "villas-acs" # The name of this VILLASnode. Might by used by node-types # to identify themselves (default is the hostname). + +log = { + level = 5; # The level of verbosity for debug messages + # Higher number => increased verbosity + + faciltities = [ "path", "socket" ]; # The list of enabled debug faciltities. + # If omitted, all faciltities are enabled + # For a full list of available faciltities, check lib/log.c + + file = "/var/log/villas-node.log"; # File for logs +}; + http = { htdocs = "/villas/web/socket/", # Root directory of internal webserver port = 80 # Port for HTTP connections diff --git a/include/villas/cfg.h b/include/villas/cfg.h index 9d8dcea75..d9640abd0 100644 --- a/include/villas/cfg.h +++ b/include/villas/cfg.h @@ -48,64 +48,4 @@ void cfg_destroy(config_t *cfg); int cfg_parse(const char *filename, config_t *cfg, struct settings *set, struct list *nodes, struct list *paths); -/** Parse the global section of a configuration file. - * - * @param cfg A libconfig object pointing to the root of the file - * @param set The global configuration file - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ -int cfg_parse_global(config_setting_t *cfg, struct settings *set); - -/** Parse a single path and add it to the global configuration. - * - * @param cfg A libconfig object pointing to the path - * @param paths Add new paths to this linked list - * @param nodes A linked list of all existing nodes - * @param set The global configuration structure - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ -int cfg_parse_path(config_setting_t *cfg, - struct list *paths, struct list *nodes, struct settings *set); - -/** Parse an array or single node and checks if they exist in the "nodes" section. - * - * Examples: - * out = [ "sintef", "scedu" ] - * out = "acs" - * - * @param cfg The libconfig object handle for "out". - * @param nodes The nodes will be added to this list. - * @param all This list contains all valid nodes. - */ -int cfg_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all); - -/** Parse an array or single hook function. - * - * Examples: - * hooks = [ "print", "fir" ] - * hooks = "log" - **/ -int cfg_parse_hooklist(config_setting_t *cfg, struct list *hooks); - -/** Parse a single hook and append it to the list. - * A hook definition is composed of the hook name and optional parameters - * seperated by a colon. - * - * Examples: - * "print:stdout" - */ -int cfg_parse_hook(config_setting_t *cfg, struct list *list); - -/** Parse a single node and add it to the global configuration. - * - * @param cfg A libconfig object pointing to the node. - * @param nodes Add new nodes to this linked list. - * @param set The global configuration structure - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ -int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *set); - #endif /* _CFG_H_ */ diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 66501985b..cf693305b 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -47,6 +47,7 @@ struct path; struct hook; struct sample; struct settings; +typedef struct config_setting_t config_setting_t; /** This is a list of hooks which can be used in the configuration file. */ extern struct list hooks; @@ -176,4 +177,21 @@ int hook_fix_ts(struct hook *h, int when, struct hook_info *j); int hook_restart(struct hook *h, int when, struct hook_info *j); int hook_drop(struct hook *h, int when, struct hook_info *j); +/** Parse an array or single hook function. + * + * Examples: + * hooks = [ "print", "fir" ] + * hooks = "log" + */ +int hook_parse_list(struct list *list, config_setting_t *cfg); + +/** Parse a single hook and append it to the list. + * A hook definition is composed of the hook name and optional parameters + * seperated by a colon. + * + * Examples: + * "print:stdout" + */ +int hook_parse(config_setting_t *cfg, struct list *list); + #endif /** _HOOKS_H_ @} */ diff --git a/include/villas/log.h b/include/villas/log.h index c57d686bf..c5a8e1a56 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -42,12 +42,12 @@ enum debug_facilities { /* Node-types */ DBG_SOCKET = (1 << 16), - DBG_FILE = (1 << 17), - DBG_FPGA = (1 << 18), - DBG_NGSI = (1 << 19), - DBG_WEBSOCKET = (1 << 20), + DBG_WEBSOCKET = (1 << 17), + DBG_FILE = (1 << 18), + DBG_FPGA = (1 << 19), + DBG_NGSI = (1 << 20), DBG_OPAL = (1 << 21), - DBG_NODE = (0xFF << 16) + DBG_NODES = (0xFF << 16) }; /** Change log indention for current thread. @@ -63,15 +63,14 @@ int log_indent(int levels); */ void log_outdent(int *); -/** Set the verbosity level of debug messages. +/** Reset the wallclock of debug messages. * * @param lvl The new debug level. * @param fac The new mask for debug facilities. */ -void log_setlevel(int lvl, int fac); +void log_init(int lvl, int fac, const char *path); -/** Reset the wallclock of debug messages. */ -void log_init(); +int log_lookup_facility(const char *facility_name); /** Logs variadic messages to stdout. * diff --git a/include/villas/node.h b/include/villas/node.h index d57553402..defbe2b17 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -30,8 +30,9 @@ __attribute__((constructor)) static void __register() { \ extern struct list node_types; /**< Vtable for virtual node sub types */ /* Forward declarations */ -struct config_setting_t cfg; struct node_type; +struct settings; +typedef struct config_setting_t config_setting_t; /** The data structure for a node. * @@ -219,12 +220,6 @@ int node_start(struct node *n); */ int node_stop(struct node *n); -/** Parse node connection details. - * - * @see node_type::parse - */ -int node_parse(struct node *n, config_setting_t *cfg); - /** Return a pointer to a string which should be used to print this node. * * @see node::_name‚ @@ -256,4 +251,26 @@ int node_read(struct node *n, struct sample *smps[], unsigned cnt); int node_write(struct node *n, struct sample *smps[], unsigned cnt); +/** Parse an array or single node and checks if they exist in the "nodes" section. + * + * Examples: + * out = [ "sintef", "scedu" ] + * out = "acs" + * + * @param cfg The libconfig object handle for "out". + * @param nodes The nodes will be added to this list. + * @param all This list contains all valid nodes. + */ +int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all); + +/** Parse a single node and add it to the global configuration. + * + * @param cfg A libconfig object pointing to the node. + * @param nodes Add new nodes to this linked list. + * @param set The global configuration structure + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ +int node_parse(struct node *n, config_setting_t *cfg, struct settings *set); + #endif /** _NODE_H_ @} */ diff --git a/include/villas/path.h b/include/villas/path.h index c9e5104aa..f3913265d 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -28,6 +28,9 @@ #include "pool.h" #include "stats.h" +/* Forward declarations */ +typedef struct config_setting_t config_setting_t; + struct path_source { struct node *node; @@ -62,16 +65,20 @@ struct path struct list hooks; /**< List of function pointers to hooks */ int enabled; /**< Is this path enabled */ + int reverse; /**< This path as a matching reverse path */ pthread_t tid; /**< The thread id for this path */ char *_name; /**< Singleton: A string which is used to print this path to screen. */ - struct stats_delta *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ + struct stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ }; +/** Allocate memory for a new path */ +struct path * path_create(); + /** Initialize internal data structures. */ int path_init(struct path *p); @@ -120,4 +127,15 @@ int path_reverse(struct path *p, struct path *r); /** Check if node is used as source or destination of a path. */ int path_uses_node(struct path *p, struct node *n); +/** Parse a single path and add it to the global configuration. + * + * @param cfg A libconfig object pointing to the path + * @param p Pointer to the allocated memory for this path + * @param nodes A linked list of all existing nodes + * @param set The global configuration structure + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ +int path_parse(struct path *p, config_setting_t *cfg, struct list *nodes, struct settings *set); + #endif /** _PATH_H_ @} */ diff --git a/lib/cfg.c b/lib/cfg.c index 038744dc9..6f1328bc2 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -19,6 +19,88 @@ #include "path.h" #include "hooks.h" +static int cfg_parse_log(config_setting_t *cfg, struct settings *set) +{ + config_setting_t *cfg_facilities; + + if (!config_setting_lookup_int(cfg, "level", &set->log.level)) + set->log.level = V; + + if (!config_setting_lookup_string(cfg, "file", &set->log.file)) + set->log.file = NULL; + + cfg_facilities = config_setting_get_member(cfg, "facilities"); + if (cfg_facilities) { + set->log.facilities = 0; + + for (int i = 0; i < config_setting_length(cfg); i++) { + int facility; + const char *str; + config_setting_t *elm = config_setting_get_elem(cfg, i); + + str = config_setting_get_string(elm); + if (!str) + cerror(elm, "Facilties must be configured as an array of strings"); + + facility = log_lookup_facility(str); + if (!facility) + cerror(elm, "%s is an unknown debug facility", str); + + set->log.facilities |= facility; + } + } + else /* By default we enable all faciltities */ + set->log.facilities = ~0; + + return 0; +} + +static int cfg_parse_plugins(config_setting_t *cfg) +{ + if (!config_setting_is_array(cfg)) + cerror(cfg, "Setting 'plugins' must be a list of strings"); + + for (int i = 0; i < config_setting_length(cfg); i++) { + void *handle; + const char *path; + + path = config_setting_get_string_elem(cfg, i); + if (!path) + cerror(cfg, "Setting 'plugins' must be a list of strings"); + + handle = dlopen(path, RTLD_NOW); + if (!handle) + error("Failed to load plugin %s", dlerror()); + } + + return 0; +} + +static int cfg_parse_global(config_setting_t *cfg, struct settings *set) +{ + config_setting_t *cfg_plugins, *cfg_log; + + if (!config_setting_lookup_int(cfg, "affinity", &set->affinity)) + set->affinity = 0; + + if (!config_setting_lookup_int(cfg, "priority", &set->priority)) + set->priority = 0; + + if (!config_setting_lookup_float(cfg, "stats", &set->stats)) + set->stats = 0; + + + cfg_log = config_setting_get_member(cfg, "log"); + if (cfg_log) + cfg_parse_log(cfg_log, set); + + cfg_plugins = config_setting_get_member(cfg, "plugins"); + if (cfg_plugins) + cfg_parse_plugins(cfg_plugins); + + return 0; +} + void cfg_init(config_t *cfg) { config_init(cfg); @@ -79,7 +161,25 @@ int cfg_parse(const char *filename, config_t *cfg, struct settings *set, for (int i = 0; i < config_setting_length(cfg_nodes); i++) { config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i); - cfg_parse_node(cfg_node, nodes, set); + + struct node_type *vt; + const char *type; + + /* Required settings */ + if (!config_setting_lookup_string(cfg_node, "type", &type)) + cerror(cfg_node, "Missing node type"); + + vt = list_lookup(&node_types, type); + if (!vt) + cerror(cfg_node, "Invalid node type: %s", type); + + struct node *n = node_create(vt); + + ret = node_parse(n, cfg_node, set); + if (ret) + cerror(cfg_node, "Failed to parse node"); + + list_push(nodes, n); } } @@ -91,286 +191,26 @@ int cfg_parse(const char *filename, config_t *cfg, struct settings *set, for (int i = 0; i < config_setting_length(cfg_paths); i++) { config_setting_t *cfg_path = config_setting_get_elem(cfg_paths, i); - cfg_parse_path(cfg_path, paths, nodes, set); + + struct path *p = path_create(); + + ret = path_parse(p, cfg_path, nodes, set); + if (ret) + cerror(cfg_path, "Failed to parse path"); + + list_push(paths, p); + + if (p->reverse) { + struct path *r = path_create(); + + ret = path_reverse(p, r); + if (ret) + cerror(cfg_path, "Failed to reverse path %s", path_name(p)); + + list_push(paths, r); + } } } return 0; -} - -int cfg_parse_plugins(config_setting_t *cfg) -{ - if (!config_setting_is_array(cfg)) - cerror(cfg, "Setting 'plugins' must be a list of strings"); - - for (int i = 0; i < config_setting_length(cfg); i++) { - void *handle; - const char *path; - - path = config_setting_get_string_elem(cfg, i); - if (!path) - cerror(cfg, "Setting 'plugins' must be a list of strings"); - - handle = dlopen(path, RTLD_NOW); - if (!handle) - error("Failed to load plugin %s", dlerror()); - } - - return 0; -} - -int cfg_parse_global(config_setting_t *cfg, struct settings *set) -{ - config_setting_t *cfg_plugins; - - if (!config_setting_lookup_int(cfg, "affinity", &set->affinity)) - set->affinity = 0; - - if (!config_setting_lookup_int(cfg, "priority", &set->priority)) - set->priority = 0; - - if (!config_setting_lookup_int(cfg, "debug", &set->debug)) - set->debug = V; - - if (!config_setting_lookup_float(cfg, "stats", &set->stats)) - set->stats = 0; - - cfg_plugins = config_setting_get_member(cfg, "plugins"); - if (cfg_plugins) - cfg_parse_plugins(cfg_plugins); - - log_setlevel(set->debug, -1); - - return 0; -} - -int cfg_parse_path(config_setting_t *cfg, - struct list *paths, struct list *nodes, struct settings *set) -{ - config_setting_t *cfg_out, *cfg_hook; - const char *in; - int ret, reverse, samplelen, queuelen; - struct path *p; - - struct node *source; - struct list destinations; - - /* Allocate memory and intialize path structure */ - p = alloc(sizeof(struct path)); - - /* Input node */ - if (!config_setting_lookup_string(cfg, "in", &in) && - !config_setting_lookup_string(cfg, "from", &in) && - !config_setting_lookup_string(cfg, "src", &in) && - !config_setting_lookup_string(cfg, "source", &in)) - cerror(cfg, "Missing input node for path"); - - source = list_lookup(nodes, in); - if (!source) - cerror(cfg, "Invalid input node '%s'", in); - - /* Output node(s) */ - if (!(cfg_out = config_setting_get_member(cfg, "out")) && - !(cfg_out = config_setting_get_member(cfg, "to")) && - !(cfg_out = config_setting_get_member(cfg, "dst")) && - !(cfg_out = config_setting_get_member(cfg, "dest")) && - !(cfg_out = config_setting_get_member(cfg, "sink"))) - cerror(cfg, "Missing output nodes for path"); - - list_init(&destinations); - ret = cfg_parse_nodelist(cfg_out, &destinations, nodes); - if (ret <= 0) - cerror(cfg_out, "Invalid output nodes"); - - /* Optional settings */ - list_init(&p->hooks); - cfg_hook = config_setting_get_member(cfg, "hook"); - if (cfg_hook) - cfg_parse_hooklist(cfg_hook, &p->hooks); - - if (!config_setting_lookup_bool(cfg, "reverse", &reverse)) - reverse = 0; - if (!config_setting_lookup_bool(cfg, "enabled", &p->enabled)) - p->enabled = 1; - if (!config_setting_lookup_int(cfg, "values", &samplelen)) - samplelen = DEFAULT_VALUES; - if (!config_setting_lookup_int(cfg, "queuelen", &queuelen)) - queuelen = DEFAULT_QUEUELEN; - - if (!IS_POW2(queuelen)) { - queuelen = LOG2_CEIL(queuelen); - warn("Queue length should always be a power of 2. Adjusting to %d", queuelen); - } - - p->cfg = cfg; - - /* Check if nodes are suitable */ - if (source->_vt->read == NULL) - cerror(cfg, "Input node '%s' is not supported as a source.", node_name(source)); - - p->source = alloc(sizeof(struct path_source)); - p->source->node = source; - p->source->samplelen = samplelen; - - list_foreach(struct node *n, &destinations) { - if (n->_vt->write == NULL) - cerror(cfg_out, "Output node '%s' is not supported as a destination.", node_name(n)); - - struct path_destination *pd = alloc(sizeof(struct path_destination)); - - pd->node = n; - pd->queuelen = queuelen; - - list_push(&p->destinations, pd); - } - - list_push(paths, p); - - if (reverse) { - struct path *r = alloc(sizeof(struct path)); - - ret = path_reverse(p, r); - if (ret) - cerror(cfg, "Failed to reverse path %s", path_name(p)); - - list_push(paths, r); - } - - list_destroy(&destinations, NULL, false); - - return 0; -} - -int cfg_parse_nodelist(config_setting_t *cfg, struct list *list, struct list *all) { - const char *str; - struct node *node; - - switch (config_setting_type(cfg)) { - case CONFIG_TYPE_STRING: - str = config_setting_get_string(cfg); - if (str) { - node = list_lookup(all, str); - if (node) - list_push(list, node); - else - cerror(cfg, "Unknown outgoing node '%s'", str); - } - else - cerror(cfg, "Invalid outgoing node"); - break; - - case CONFIG_TYPE_ARRAY: - for (int i = 0; i < config_setting_length(cfg); i++) { - config_setting_t *elm = config_setting_get_elem(cfg, i); - - str = config_setting_get_string(elm); - if (str) { - node = list_lookup(all, str); - if (!node) - cerror(elm, "Unknown outgoing node '%s'", str); - else if (node->_vt->write == NULL) - cerror(cfg, "Output node '%s' is not supported as a sink.", node_name(node)); - - list_push(list, node); - } - else - cerror(cfg, "Invalid outgoing node"); - } - break; - - default: - cerror(cfg, "Invalid output node(s)"); - } - - return list_length(list); -} - -int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *set) -{ - const char *type, *name; - int ret; - - struct node *n; - struct node_type *vt; - - /* Required settings */ - if (!config_setting_lookup_string(cfg, "type", &type)) - cerror(cfg, "Missing node type"); - - name = config_setting_name(cfg); - - vt = list_lookup(&node_types, type); - if (!vt) - cerror(cfg, "Invalid type for node '%s'", config_setting_name(cfg)); - - n = node_create(vt); - - n->name = name; - n->cfg = cfg; - - ret = node_parse(n, cfg); - if (ret) - cerror(cfg, "Failed to parse node '%s'", node_name(n)); - - if (config_setting_lookup_int(cfg, "vectorize", &n->vectorize)) { - config_setting_t *cfg_vectorize = config_setting_lookup(cfg, "vectorize"); - - if (n->vectorize <= 0) - cerror(cfg_vectorize, "Invalid value for `vectorize` %d. Must be natural number!", n->vectorize); - if (vt->vectorize && vt->vectorize < n->vectorize) - cerror(cfg_vectorize, "Invalid value for `vectorize`. Node type %s requires a number smaller than %d!", - node_name_type(n), vt->vectorize); - } - else - n->vectorize = 1; - - if (!config_setting_lookup_int(cfg, "affinity", &n->affinity)) - n->affinity = set->affinity; - - list_push(nodes, n); - - return ret; -} - -int cfg_parse_hooklist(config_setting_t *cfg, struct list *list) { - switch (config_setting_type(cfg)) { - case CONFIG_TYPE_STRING: - cfg_parse_hook(cfg, list); - break; - - case CONFIG_TYPE_ARRAY: - for (int i = 0; i < config_setting_length(cfg); i++) - cfg_parse_hook(config_setting_get_elem(cfg, i), list); - break; - - default: - cerror(cfg, "Invalid hook functions"); - } - - return list_length(list); -} - -int cfg_parse_hook(config_setting_t *cfg, struct list *list) -{ - struct hook *hook, *copy; - char *name, *param; - const char *hookline = config_setting_get_string(cfg); - if (!hookline) - cerror(cfg, "Invalid hook function"); - - name = strtok((char *) hookline, ":"); - param = strtok(NULL, ""); - - debug(3, "Hook: %s => %s", name, param); - - hook = list_lookup(&hooks, name); - if (!hook) - cerror(cfg, "Unknown hook function '%s'", name); - - copy = memdup(hook, sizeof(struct hook)); - copy->parameter = param; - - list_push(list, copy); - - return 0; -} +} \ No newline at end of file diff --git a/lib/hooks.c b/lib/hooks.c index 15492a52d..c6f9e4196 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -8,6 +8,7 @@ #include #include +#include #include "timing.h" #include "config.h" @@ -101,4 +102,53 @@ void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_c } return h->_vd; +} + +/** Parse an array or single hook function. + * + * Examples: + * hooks = [ "print", "fir" ] + * hooks = "log" + */ +int hook_parse_list(struct list *list, config_setting_t *cfg) { + switch (config_setting_type(cfg)) { + case CONFIG_TYPE_STRING: + hook_parse(cfg, list); + break; + + case CONFIG_TYPE_ARRAY: + for (int i = 0; i < config_setting_length(cfg); i++) + hook_parse(config_setting_get_elem(cfg, i), list); + break; + + default: + cerror(cfg, "Invalid hook functions"); + } + + return list_length(list); +} + +int hook_parse(config_setting_t *cfg, struct list *list) +{ + struct hook *hook, *copy; + char *name, *param; + const char *hookline = config_setting_get_string(cfg); + if (!hookline) + cerror(cfg, "Invalid hook function"); + + name = strtok((char *) hookline, ":"); + param = strtok(NULL, ""); + + debug(3, "Hook: %s => %s", name, param); + + hook = list_lookup(&hooks, name); + if (!hook) + cerror(cfg, "Unknown hook function '%s'", name); + + copy = memdup(hook, sizeof(struct hook)); + copy->parameter = param; + + list_push(list, copy); + + return 0; } \ No newline at end of file diff --git a/lib/log.c b/lib/log.c index 74e8d1694..144a985c6 100644 --- a/lib/log.c +++ b/lib/log.c @@ -34,6 +34,27 @@ static unsigned facilities = ~0; /** A global clock used to prefix the log messages. */ static struct timespec epoch; +/** Handle to log file */ +static FILE *file; + +static const char *facility_names[] = { + "pool", // DBG_POOL + "queue", // DBG_QUEUE + "config", // DBG_CONFIG + "hook", // DBG_HOOK + "path", // DBG_PATH + "mem", // DBG_MEM + + /* Node-types */ + "socket", // DBG_SOCKET + "websocket", // DBG_WEBSOCKET + "file", // DBG_FILE + "fpga", // DBG_FPGA + "ngsi", // DBG_NGSI + "opal", // DBG_OPAL + NULL +}; + #ifdef __GNUC__ /** The current log indention level (per thread!). */ static __thread int indent = 0; @@ -51,16 +72,29 @@ void log_outdent(int *old) } #endif -void log_setlevel(int lvl, int fac) +void log_init(int lvl, int fac, const char *path) { + char *fac_str = NULL; + + /* Initialize global variables */ + epoch = time_now(); level = lvl; - debug(10, "Switched to debug level %u", level); + facilities = fac; + + if (path) + file = fopen(path, "a"); + + debug(10, "Started logging: level = %u, faciltities = %s", level, fac_str); } -void log_init() +int log_lookup_facility(const char *facility_name) { - epoch = time_now(); - debug(10, "Debug clock resetted"); + for (int i = 0; facility_names[i]; i++) { + if (!strcmp(facility_name, facility_names[i])) + return 1 << i; + } + + return 0; } void log_print(const char *lvl, const char *fmt, ...) @@ -99,6 +133,10 @@ void log_vprint(const char *lvl, const char *fmt, va_list ap) OpalPrint("VILLASnode: %s\n", buf); #endif fprintf(stderr, "\r%s\n", buf); + + if (file) + fprintf(file, "%s\n", buf); + free(buf); } diff --git a/lib/node.c b/lib/node.c index 9bfe0a4c6..194b72357 100644 --- a/lib/node.c +++ b/lib/node.c @@ -7,20 +7,18 @@ *********************************************************************************/ #include +#include + #include "sample.h" #include "node.h" #include "cfg.h" #include "utils.h" +#include "config.h" /** List of registered node-types */ struct list node_types = LIST_INIT(); -int node_parse(struct node *n, config_setting_t *cfg) -{ - return n->_vt->parse ? n->_vt->parse(n, cfg) : 0; -} - int node_read(struct node *n, struct sample *smps[], unsigned cnt) { int nread = 0; @@ -207,3 +205,98 @@ void node_destroy(struct node *n) free(n->_name); free(n); } + +/** Parse an array or single node and checks if they exist in the "nodes" section. + * + * Examples: + * out = [ "sintef", "scedu" ] + * out = "acs" + * + * @param cfg The libconfig object handle for "out". + * @param nodes The nodes will be added to this list. + * @param all This list contains all valid nodes. + */ +int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all) { + const char *str; + struct node *node; + + switch (config_setting_type(cfg)) { + case CONFIG_TYPE_STRING: + str = config_setting_get_string(cfg); + if (str) { + node = list_lookup(all, str); + if (node) + list_push(list, node); + else + cerror(cfg, "Unknown outgoing node '%s'", str); + } + else + cerror(cfg, "Invalid outgoing node"); + break; + + case CONFIG_TYPE_ARRAY: + for (int i = 0; i < config_setting_length(cfg); i++) { + config_setting_t *elm = config_setting_get_elem(cfg, i); + + str = config_setting_get_string(elm); + if (str) { + node = list_lookup(all, str); + if (!node) + cerror(elm, "Unknown outgoing node '%s'", str); + else if (node->_vt->write == NULL) + cerror(cfg, "Output node '%s' is not supported as a sink.", node_name(node)); + + list_push(list, node); + } + else + cerror(cfg, "Invalid outgoing node"); + } + break; + + default: + cerror(cfg, "Invalid output node(s)"); + } + + return list_length(list); +} + +int node_parse(struct node *n, config_setting_t *cfg, struct settings *set) +{ + struct node_type *vt; + const char *type, *name; + int ret; + + name = config_setting_name(cfg); + + if (!config_setting_lookup_string(cfg, "type", &type)) + cerror(cfg, "Missing node type"); + + vt = list_lookup(&node_types, type); + if (!vt) + cerror(cfg, "Invalid type for node '%s'", config_setting_name(cfg)); + + n->name = name; + n->cfg = cfg; + + ret = n->_vt->parse ? n->_vt->parse(n, cfg) : 0; + if (ret) + cerror(cfg, "Failed to parse node '%s'", node_name(n)); + + if (config_setting_lookup_int(cfg, "vectorize", &n->vectorize)) { + config_setting_t *cfg_vectorize = config_setting_lookup(cfg, "vectorize"); + + if (n->vectorize <= 0) + cerror(cfg_vectorize, "Invalid value for `vectorize` %d. Must be natural number!", n->vectorize); + if (vt->vectorize && vt->vectorize < n->vectorize) + cerror(cfg_vectorize, "Invalid value for `vectorize`. Node type %s requires a number smaller than %d!", + node_name_type(n), vt->vectorize); + } + else + n->vectorize = 1; + + if (!config_setting_lookup_int(cfg, "affinity", &n->affinity)) + n->affinity = set->affinity; + + return ret; +} + diff --git a/lib/path.c b/lib/path.c index e5c7728b9..4a6c7825b 100644 --- a/lib/path.c +++ b/lib/path.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "config.h" #include "utils.h" @@ -177,6 +178,11 @@ const char * path_name(struct path *p) return p->_name; } +struct path * path_create() +{ + return (struct path *) alloc(sizeof(struct path)); +} + int path_init(struct path *p) { int ret, max_queuelen = 0; @@ -294,5 +300,85 @@ int path_reverse(struct path *p, struct path *r) list_push(&r->hooks, hc); } + return 0; +} + +int path_parse(struct path *p, config_setting_t *cfg, struct list *nodes, struct settings *set) +{ + config_setting_t *cfg_out, *cfg_hook; + const char *in; + int ret, samplelen, queuelen; + + struct node *source; + struct list destinations; + + /* Input node */ + if (!config_setting_lookup_string(cfg, "in", &in) && + !config_setting_lookup_string(cfg, "from", &in) && + !config_setting_lookup_string(cfg, "src", &in) && + !config_setting_lookup_string(cfg, "source", &in)) + cerror(cfg, "Missing input node for path"); + + source = list_lookup(nodes, in); + if (!source) + cerror(cfg, "Invalid input node '%s'", in); + + /* Output node(s) */ + if (!(cfg_out = config_setting_get_member(cfg, "out")) && + !(cfg_out = config_setting_get_member(cfg, "to")) && + !(cfg_out = config_setting_get_member(cfg, "dst")) && + !(cfg_out = config_setting_get_member(cfg, "dest")) && + !(cfg_out = config_setting_get_member(cfg, "sink"))) + cerror(cfg, "Missing output nodes for path"); + + list_init(&destinations); + ret = node_parse_list(&destinations, cfg_out, nodes); + if (ret <= 0) + cerror(cfg_out, "Invalid output nodes"); + + /* Optional settings */ + list_init(&p->hooks); + cfg_hook = config_setting_get_member(cfg, "hook"); + if (cfg_hook) + hook_parse_list(&p->hooks, cfg_hook); + + if (!config_setting_lookup_bool(cfg, "reverse", &p->reverse)) + p->reverse = 0; + if (!config_setting_lookup_bool(cfg, "enabled", &p->enabled)) + p->enabled = 1; + if (!config_setting_lookup_int(cfg, "values", &samplelen)) + samplelen = DEFAULT_VALUES; + if (!config_setting_lookup_int(cfg, "queuelen", &queuelen)) + queuelen = DEFAULT_QUEUELEN; + + if (!IS_POW2(queuelen)) { + queuelen = LOG2_CEIL(queuelen); + warn("Queue length should always be a power of 2. Adjusting to %d", queuelen); + } + + p->cfg = cfg; + + /* Check if nodes are suitable */ + if (source->_vt->read == NULL) + cerror(cfg, "Input node '%s' is not supported as a source.", node_name(source)); + + p->source = alloc(sizeof(struct path_source)); + p->source->node = source; + p->source->samplelen = samplelen; + + list_foreach(struct node *n, &destinations) { + if (n->_vt->write == NULL) + cerror(cfg_out, "Output node '%s' is not supported as a destination.", node_name(n)); + + struct path_destination *pd = alloc(sizeof(struct path_destination)); + + pd->node = n; + pd->queuelen = queuelen; + + list_push(&p->destinations, pd); + } + + list_destroy(&destinations, NULL, false); + return 0; } \ No newline at end of file diff --git a/src/fpga.c b/src/fpga.c index da8205076..4c8617551 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -47,7 +47,7 @@ void usage() int main(int argc, char *argv[]) { - int ret; + int ret, level = -1; struct fpga *fpga; config_t config; @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) while ((c = getopt(argc-1, argv+1, "d:")) != -1) { switch (c) { case 'd': - log_setlevel(strtoul(optarg, &endptr, 10), ~0); + level = strtoul(optarg, &endptr, 10); break; case '?': @@ -82,6 +82,9 @@ int main(int argc, char *argv[]) info("Parsing configuration"); cfg_parse(argv[1], &config, &settings, NULL, NULL); + info("Initialize logging system"); + log_init(level > 0 ? level : settings.log.level, settings.log.facilities, settings.log.file); + info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); diff --git a/src/hook.c b/src/hook.c index d30133410..87e961444 100644 --- a/src/hook.c +++ b/src/hook.c @@ -36,7 +36,7 @@ static void usage() int main(int argc, char *argv[]) { - int j, ret, cnt = 1; + int j, ret, cnt = 1, level = -1; char *name, *parameter; @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) cnt = atoi(optarg); break; case 'd': - log_setlevel(atoi(optarg), -1); + level = atoi(optarg); break; case 'h': case '?': @@ -83,6 +83,9 @@ int main(int argc, char *argv[]) struct pool pool; struct sample *smps[cnt]; + + info("Initialize logging system"); + log_init(level, -1, NULL); ret = pool_init(&pool, 10 * cnt, SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); if (ret) diff --git a/src/node.c b/src/node.c index 4b8d9f681..99e73a25c 100644 --- a/src/node.c +++ b/src/node.c @@ -108,7 +108,6 @@ int main(int argc, char *argv[]) char *configfile = (argc == 2) ? argv[1] : "opal-shmem.conf"; - log_init(); info("This is VILLASnode %s (built on %s, %s)", BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__))); @@ -122,6 +121,9 @@ int main(int argc, char *argv[]) info("Parsing configuration"); cfg_parse(configfile, &config, &settings, &nodes, &paths); + + info("Initialize logging system"); + log_init(settings.log.level, settings.log.facilities, settings.log.file); info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); diff --git a/src/pipe.c b/src/pipe.c index 16c4e0a35..26b18683f 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -171,11 +171,10 @@ static void * recv_loop(void *ctx) int main(int argc, char *argv[]) { - int ret; + int ret, level = -1; char c; ptid = pthread_self(); - log_init(); /* Parse command line arguments */ if (argc < 3) @@ -197,7 +196,7 @@ int main(int argc, char *argv[]) sendd.enabled = false; // receive only break; case 'd': - log_setlevel(atoi(optarg), -1); + level = atoi(optarg); break; case 'h': case '?': @@ -221,6 +220,9 @@ int main(int argc, char *argv[]) info("Parsing configuration"); cfg_parse(argv[1], &config, &settings, &nodes, NULL); + + info("Initialize logging system"); + log_init(level > 0 ? level : settings.log.level, settings.log.facilities, settings.log.file); info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); diff --git a/src/signal.c b/src/signal.c index 601c350d3..05b06e0ea 100644 --- a/src/signal.c +++ b/src/signal.c @@ -56,8 +56,6 @@ int main(int argc, char *argv[]) int values = 1; int limit = -1; int counter; - - log_init(); if (argc < 2) { usage(); @@ -111,7 +109,7 @@ int main(int argc, char *argv[]) check: if (optarg == endptr) error("Failed to parse parse option argument '-%c %s'", c, optarg); } - + /* Allocate memory for message buffer */ struct sample *s = alloc(SAMPLE_LEN(values)); diff --git a/src/test.c b/src/test.c index 8e4f56ae6..eb7424c73 100644 --- a/src/test.c +++ b/src/test.c @@ -84,11 +84,12 @@ int main(int argc, char *argv[]) sigaction(SIGINT, &sa_quit, NULL); list_init(&nodes); - - log_init(); info("Parsing configuration"); cfg_parse(argv[1], &config, &settings, &nodes, NULL); + + info("Initialize logging system"); + log_init(settings.log.level, settings.log.facilities, settings.log.file); info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); From d1d43692673203218fea71698f3d51f18c112939 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 13:00:23 -0500 Subject: [PATCH 055/211] properly initialize other applications apart from villas-node --- src/fpga.c | 3 +++ src/hook.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/fpga.c b/src/fpga.c index 4c8617551..bd7926ad8 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -87,6 +87,9 @@ int main(int argc, char *argv[]) info("Initialize real-time system"); rt_init(settings.affinity, settings.priority); + + info("Initialize memory system"); + memory_init(); /* Initialize VILLASfpga card */ config_setting_t *cfg_root = config_root_setting(&config); diff --git a/src/hook.c b/src/hook.c index 87e961444..75bda2904 100644 --- a/src/hook.c +++ b/src/hook.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "config.h" @@ -86,6 +87,12 @@ int main(int argc, char *argv[]) info("Initialize logging system"); log_init(level, -1, NULL); + + info("Initialize real-time system"); + rt_init(-1, 50); + + info("Initialize memory system"); + memory_init(); ret = pool_init(&pool, 10 * cnt, SAMPLE_LEN(DEFAULT_VALUES), &memtype_hugepage); if (ret) From a93952aaae30ecc568380bff2a1395ed8d0a41b5 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 13:01:17 -0500 Subject: [PATCH 056/211] statistics are almost working again --- include/villas/stats.h | 3 ++- lib/hooks.c | 5 +++-- lib/hooks/hooks-internal.c | 4 ++-- lib/hooks/hooks-stats.c | 43 +++++++++++++++++++++++--------------- lib/path.c | 4 ++-- lib/stats.c | 32 +++++++++++++++++----------- 6 files changed, 55 insertions(+), 36 deletions(-) diff --git a/include/villas/stats.h b/include/villas/stats.h index dc69beb41..833823f78 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -36,13 +36,14 @@ enum stats_id { struct stats_delta { double values[STATS_COUNT]; + int update; /**< Bitmask of stats_id. Only those which are masked will be updated */ struct sample *last; }; struct stats { struct hist histograms[STATS_COUNT]; - struct sample *last; + struct stats_delta *delta; }; int stats_init(struct stats *s); diff --git a/lib/hooks.c b/lib/hooks.c index c6f9e4196..cc74110eb 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -70,9 +70,10 @@ int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when) list_foreach(struct hook *h, &p->hooks) { if (h->type & when) { - debug(DBG_HOOK | 22, "Running hook when=%u '%s' prio=%u, cnt=%zu", when, h->name, h->priority, cnt); - cnt = h->cb(h, when, &i); + + debug(DBG_HOOK | 22, "Ran hook '%s' when=%u prio=%u, cnt=%zu", h->name, when, h->priority, cnt); + if (cnt == 0) break; } diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 81673a3c3..735fa50df 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -77,8 +77,8 @@ int hook_drop(struct hook *h, int when, struct hook_info *j) dist = h->last->sequence - (int32_t) h->prev->sequence; if (dist <= 0) { warn("Dropped sample: dist = %d, i = %d", dist, i); - if (j->path) - stats_update(j->path->stats, STATS_DROPPED, dist); + if (j->path && j->path->stats) + stats_update(j->path->stats->delta, STATS_DROPPED, dist); } else { struct sample *tmp; diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index bd78d3c87..38f02916f 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -20,11 +20,16 @@ int hook_stats(struct hook *h, int when, struct hook_info *j) struct stats *s = hook_storage(h, when, sizeof(struct stats), (ctor_cb_t) stats_init, (dtor_cb_t) stats_destroy); switch (when) { + case HOOK_INIT: + if (j->path) + j->path->stats = s; + break; + case HOOK_READ: assert(j->smps); - assert(j->path); - stats_collect(j->path->stats, j->smps, j->cnt); + stats_collect(s->delta, j->smps, j->cnt); + stats_commit(s, s->delta); break; case HOOK_PATH_STOP: @@ -45,37 +50,41 @@ int hook_stats(struct hook *h, int when, struct hook_info *j) return j->cnt; } -#if 0 /* currently broken */ -REGISTER_HOOK("stats_send", "Send path statistics to another node", 99, 0, hook_stats_send, HOOK_STORAGE | HOOK_DESTROY | HOOK_PERIODIC | HOOK_PATH) -int hook_stats_send(struct hook *h, int when, struct hook_info *i) +/** @todo This is untested */ +REGISTER_HOOK("stats_send", "Send path statistics to another node", 99, 0, hook_stats_send, HOOK_STORAGE | HOOK_PATH | HOOK_READ) +int hook_stats_send(struct hook *h, int when, struct hook_info *j) { struct private { struct node *dest; + struct stats *stats; int ratio; - } *private = hook_storage(h, when, sizeof(*private)); + } *private = hook_storage(h, when, sizeof(*private), NULL, NULL); switch (when) { - case HOOK_DESTROY: + case HOOK_INIT: + assert(j->nodes); + assert(j->path); + if (!h->parameter) error("Missing parameter for hook '%s'", h->name); - if (!hook_nodes) - error("Missing reference to node list for hook '%s", h->name); - - private->dest = list_lookup(hook_nodes, h->parameter); + private->dest = list_lookup(j->nodes, h->parameter); if (!private->dest) error("Invalid destination node '%s' for hook '%s'", h->parameter, h->name); - - node_start(private->dest); + break; + case HOOK_PATH_START: + node_start(private->dest); break; - case HOOK_PERIODIC: { - stats_send(s, node); + case HOOK_PATH_STOP: + node_stop(private->dest); + break; + + case HOOK_READ: + stats_send(private->stats, private->dest); break; - } } return 0; } -#endif \ No newline at end of file diff --git a/lib/path.c b/lib/path.c index 4a6c7825b..863378380 100644 --- a/lib/path.c +++ b/lib/path.c @@ -52,7 +52,7 @@ static void path_read(struct path *p) if (enqueue != recv) { info("Hooks skipped %u out of %u samples for path %s", recv - enqueue, recv, path_name(p)); - stats_update(p->stats, STATS_SKIPPED, recv - enqueue); + stats_update(p->stats->delta, STATS_SKIPPED, recv - enqueue); } list_foreach(struct path_destination *pd, &p->destinations) { @@ -84,7 +84,7 @@ static void path_write(struct path *p) if (available == 0) break; else if (available < cnt) - warn("Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); + debug(DBG_PATH | 5, "Queue underrun for path %s: available=%u expected=%u", path_name(p), available, cnt); debug(DBG_PATH | 15, "Dequeued %u samples from queue of node %s which is part of path %s", available, node_name(pd->node), path_name(p)); diff --git a/lib/stats.c b/lib/stats.c index 6441edf85..fd137f8ca 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -37,6 +37,8 @@ int stats_init(struct stats *s) struct stats_desc *desc = &stats_table[i]; hist_create(&s->histograms[i], desc->hist.min, desc->hist.max, desc->hist.resolution); } + + s->delta = alloc(sizeof(struct stats_delta)); return 0; } @@ -46,18 +48,23 @@ void stats_destroy(struct stats *s) for (int i = 0; i < STATS_COUNT; i++) { hist_destroy(&s->histograms[i]); } + + free(s->delta); } void stats_update(struct stats_delta *d, enum stats_id id, double val) { - if (d && id >= 0 && id < STATS_COUNT) - d->values[id] = val; + assert(id >= 0 && id < STATS_COUNT); + + d->values[id] = val; + d->update |= 1 << id; } int stats_commit(struct stats *s, struct stats_delta *d) { for (int i = 0; i < STATS_COUNT; i++) { - hist_put(&s->histograms[i], d->values[i]); + if (d->update & 1 << i) + hist_put(&s->histograms[i], d->values[i]); } return 0; @@ -67,22 +74,23 @@ void stats_collect(struct stats_delta *s, struct sample *smps[], size_t cnt) { struct sample *previous = s->last; - if (previous) { - sample_put(previous); - - for (int i = 0; i < cnt; i++) { + for (int i = 0; i < cnt; i++) { + if (previous) { stats_update(s, STATS_GAP_RECEIVED, time_delta(&previous->ts.received, &smps[i]->ts.received)); stats_update(s, STATS_GAP_SAMPLE, time_delta(&previous->ts.origin, &smps[i]->ts.origin)); stats_update(s, STATS_OWD, time_delta(&smps[i]->ts.origin, &smps[i]->ts.received)); stats_update(s, STATS_GAP_SEQUENCE, smps[i]->sequence - (int32_t) previous->sequence); - - /* Make sure there is always a reference to the previous sample */ - - previous = smps[i]; } + + previous = smps[i]; } - sample_get(previous); + if (s->last) + sample_put(s->last); + + if (previous) + sample_get(previous); + s->last = previous; } From c84df390bca1ba0dc611d698ece61ed9fd4535c7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 20 Nov 2016 13:11:37 -0500 Subject: [PATCH 057/211] renamed hook related files --- include/villas/{hooks.h => hook.h} | 0 include/villas/path.h | 1 - lib/Makefile.inc | 2 +- lib/cfg.c | 2 +- lib/{hooks.c => hook.c} | 2 +- lib/hooks/{hooks-internal.c => internal.c} | 2 +- lib/hooks/{hooks-other.c => other.c} | 2 +- lib/hooks/{hooks-stats.c => stats.c} | 2 +- lib/path.c | 5 +---- plugins/hooks/example_hook.c | 2 +- src/hook.c | 2 +- src/node.c | 1 + 12 files changed, 10 insertions(+), 13 deletions(-) rename include/villas/{hooks.h => hook.h} (100%) rename lib/{hooks.c => hook.c} (99%) rename lib/hooks/{hooks-internal.c => internal.c} (99%) rename lib/hooks/{hooks-other.c => other.c} (99%) rename lib/hooks/{hooks-stats.c => stats.c} (99%) diff --git a/include/villas/hooks.h b/include/villas/hook.h similarity index 100% rename from include/villas/hooks.h rename to include/villas/hook.h diff --git a/include/villas/path.h b/include/villas/path.h index f3913265d..6d3750683 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -23,7 +23,6 @@ #include "hist.h" #include "node.h" #include "msg.h" -#include "hooks.h" #include "queue.h" #include "pool.h" #include "stats.h" diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 258c50d14..a36c1bf9f 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -4,7 +4,7 @@ LIBS = $(BUILDDIR)/libvillas.so # Object files for libvillas LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ - $(addprefix lib/, sample.c path.c node.c hooks.c \ + $(addprefix lib/, sample.c path.c node.c hook.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ queue.c memory.c stats.c \ ) \ diff --git a/lib/cfg.c b/lib/cfg.c index 6f1328bc2..b8e99ff33 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -17,7 +17,7 @@ #include "cfg.h" #include "node.h" #include "path.h" -#include "hooks.h" +#include "hook.h" static int cfg_parse_log(config_setting_t *cfg, struct settings *set) { diff --git a/lib/hooks.c b/lib/hook.c similarity index 99% rename from lib/hooks.c rename to lib/hook.c index cc74110eb..c1dd12d97 100644 --- a/lib/hooks.c +++ b/lib/hook.c @@ -13,7 +13,7 @@ #include "timing.h" #include "config.h" #include "msg.h" -#include "hooks.h" +#include "hook.h" #include "path.h" #include "utils.h" #include "node.h" diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/internal.c similarity index 99% rename from lib/hooks/hooks-internal.c rename to lib/hooks/internal.c index 735fa50df..3b7eece90 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/internal.c @@ -6,7 +6,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#include "hooks.h" +#include "hook.h" #include "timing.h" #include "sample.h" #include "path.h" diff --git a/lib/hooks/hooks-other.c b/lib/hooks/other.c similarity index 99% rename from lib/hooks/hooks-other.c rename to lib/hooks/other.c index 0a63ea5fa..f63de05d8 100644 --- a/lib/hooks/hooks-other.c +++ b/lib/hooks/other.c @@ -11,7 +11,7 @@ #include #include -#include "hooks.h" +#include "hook.h" #include "timing.h" #include "utils.h" #include "sample.h" diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/stats.c similarity index 99% rename from lib/hooks/hooks-stats.c rename to lib/hooks/stats.c index 38f02916f..9dcb9ffb5 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/stats.c @@ -6,7 +6,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#include "hooks.h" +#include "hook.h" #include "sample.h" #include "path.h" #include "utils.h" diff --git a/lib/path.c b/lib/path.c index 863378380..f585dcce0 100644 --- a/lib/path.c +++ b/lib/path.c @@ -19,6 +19,7 @@ #include "timing.h" #include "pool.h" #include "queue.h" +#include "hook.h" static void path_read(struct path *p) { @@ -199,10 +200,6 @@ int path_init(struct path *p) /* We sort the hooks according to their priority before starting the path */ list_sort(&p->hooks, hooks_sort_priority); - ret = hook_run(p, NULL, 0, HOOK_INIT); - if (ret) - error("Failed to initialize hooks of path: %s", path_name(p)); - /* Parse hook arguments */ ret = hook_run(p, NULL, 0, HOOK_PARSE); if (ret) diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index 22e1b48dc..827c33b54 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -1,4 +1,4 @@ -#include +#include #include static int hook_example(struct hook *h, int when, struct hook_info *j) diff --git a/src/hook.c b/src/hook.c index 75bda2904..648be8e0a 100644 --- a/src/hook.c +++ b/src/hook.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/node.c b/src/node.c index 99e73a25c..6db1e1d52 100644 --- a/src/node.c +++ b/src/node.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef ENABLE_OPAL_ASYNC #include From f2d50ad38d51c63e145a146657eb32dda022cfb1 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 23 Dec 2016 17:24:53 +0100 Subject: [PATCH 058/211] moving VLLASfpga tests to Criterion unit tests --- src/fpga.c | 7 +- src/fpga-tests.c => tests/fpga.c | 193 +++++++++++++++---------------- 2 files changed, 97 insertions(+), 103 deletions(-) rename src/fpga-tests.c => tests/fpga.c (63%) diff --git a/src/fpga.c b/src/fpga.c index 46895c0f6..9cd7137a1 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -27,7 +27,6 @@ /* Declarations */ int fpga_benchmarks(int argc, char *argv[], struct fpga *f); -int fpga_tests(int argc, char *argv[], struct fpga *f); struct settings settings; @@ -35,7 +34,6 @@ void usage(char *name) { printf("Usage: %s CONFIGFILE CMD [OPTIONS]\n", name); printf(" Commands:\n"); - printf(" tests Test functionality of VILLASfpga card\n"); printf(" benchmarks Do benchmarks\n\n"); printf(" Options:\n"); printf(" -d Set log level\n\n"); @@ -58,9 +56,7 @@ int main(int argc, char *argv[]) if (argc < 3) usage(argv[0]); - if (strcmp(argv[2], "tests") == 0) - subcommand = FPGA_TESTS; - else if (strcmp(argv[2], "benchmarks") == 0) + if (strcmp(argv[2], "benchmarks") == 0) subcommand = FPGA_BENCH; else usage(argv[0]); @@ -96,7 +92,6 @@ int main(int argc, char *argv[]) /* Start subcommand */ switch (subcommand) { - case FPGA_TESTS: fpga_tests(argc-optind-1, argv+optind+1, fpga); break; case FPGA_BENCH: fpga_benchmarks(argc-optind-1, argv+optind+1, fpga); break; } diff --git a/src/fpga-tests.c b/tests/fpga.c similarity index 63% rename from src/fpga-tests.c rename to tests/fpga.c index 0790a2607..c738e7410 100644 --- a/src/fpga-tests.c +++ b/tests/fpga.c @@ -13,8 +13,12 @@ #include #include +#include +#include + #include +#include #include #include @@ -23,75 +27,81 @@ #include "config.h" +#define TEST_CONFIG "/villas/etc/fpga.conf" #define TEST_LEN 0x1000 #define CPU_HZ 3392389000 -/* Forward Declarations */ -int fpga_test_intc(struct fpga *f); -int fpga_test_timer(struct fpga *f); -int fpga_test_fifo(struct fpga *f); -int fpga_test_dma(struct fpga *f); -int fpga_test_xsg(struct fpga *f); -int fpga_test_hls_dft(struct fpga *f); -int fpga_test_rtds_rtt(struct fpga *f); +static struct fpga *fpga; -int fpga_tests(int argc, char *argv[], struct fpga *f) +static config_t config; +static struct settings settings; + +static void init() { int ret; + int argc = 1; + char *argv[] = { "tests" }; + config_setting_t *cfg_root; - struct { - const char *name; - int (*func)(struct fpga *f); - } tests[] = { - { "Interrupt Controller", fpga_test_intc }, - { "Timer Counter", fpga_test_timer }, - { "FIFO", fpga_test_fifo }, - { "DMA", fpga_test_dma }, - { "XSG: multiply_add", fpga_test_xsg }, - { "HLS: hls_dft", fpga_test_hls_dft }, - { "RTDS: tight rtt", fpga_test_rtds_rtt } - }; + cfg_parse(TEST_CONFIG, &config, &settings, NULL, NULL); - for (int i = 0; i < ARRAY_LEN(tests); i++) { - ret = tests[i].func(f); + cfg_root = config_root_setting(&config); - info("%s: %s", tests[i].name, (ret == 0) ? GRN("passed") : RED("failed")); - } + ret = fpga_init(argc, argv, cfg_root); + cr_assert_eq(ret, 0, "Failed to initilize FPGA"); - return 0; + fpga = fpga_get(); + + if (criterion_options.logging_threshold < CRITERION_IMPORTANT) + fpga_dump(fpga); } -int fpga_test_intc(struct fpga *f) +static void fini() +{ + int ret; + + ret = fpga_deinit(&fpga); + cr_assert_eq(ret, 0, "Failed to de-initilize FPGA"); + + cfg_destroy(&config); + +} + +TestSuite(fpga, + .init = init, + .fini = fini, + .description = "VILLASfpga"); + +Test(fpga, intc, .description = "Interrupt Controller") { int ret; uint32_t isr; - if (!f->intc) - return -1; + cr_assert(fpga->intc); - ret = intc_enable(f->intc, 0xFF00, 0); + ret = intc_enable(fpga->intc, 0xFF00, 0); if (ret) error("Failed to enable interrupt"); /* Fake IRQs in software by writing to ISR */ - XIntc_Out32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00); + XIntc_Out32((uintptr_t) fpga->map + fpga->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00); /* Wait for 8 SW triggered IRQs */ for (int i = 0; i < 8; i++) - intc_wait(f->intc, i+8); + intc_wait(fpga->intc, i+8); /* Check ISR if all SW IRQs have been deliverd */ - isr = XIntc_In32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET); + isr = XIntc_In32((uintptr_t) fpga->map + fpga->intc->baseaddr + XIN_ISR_OFFSET); - ret = intc_disable(f->intc, 0xFF00); + ret = intc_disable(fpga->intc, 0xFF00); if (ret) error("Failed to disable interrupt"); - return (isr & 0xFF00) ? -1 : 0; /* ISR should get cleared by MSI_Grant_signal */ + cr_assert_eq(isr & 0xFF00, 0); /* ISR should get cleared by MSI_Grant_signal */ } -int fpga_test_xsg(struct fpga *f) +Test(fpga, xsg, .description = "XSG: multiply_add") { int ret; double factor, err = 0; @@ -100,12 +110,11 @@ int fpga_test_xsg(struct fpga *f) struct model_param *p; struct dma_mem mem; - xsg = ip_vlnv_lookup(&f->ips, NULL, "sysgen", "xsg_multiply", NULL); - dma = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_dma", NULL); + xsg = ip_vlnv_lookup(&fpga->ips, NULL, "sysgen", "xsg_multiply", NULL); + dma = ip_vlnv_lookup(&fpga->ips, "xilinx.com", "ip", "axi_dma", NULL); /* Check if required IP is available on FPGA */ - if (!dma || !xsg || !dma) - return -1; + cr_assert_neq(!dma || !xsg || !dma, 0); p = list_lookup(&xsg->model.parameters, "factor"); if (!p) @@ -117,10 +126,10 @@ int fpga_test_xsg(struct fpga *f) info("Model param: factor = %f", factor); - ret = switch_connect(f->sw, dma, xsg); + ret = switch_connect(fpga->sw, dma, xsg); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, xsg, dma); + ret = switch_connect(fpga->sw, xsg, dma); if (ret) error("Failed to configure switch"); @@ -143,10 +152,10 @@ int fpga_test_xsg(struct fpga *f) info("Error after FPGA operation: err = %f", err); - ret = switch_disconnect(f->sw, dma, xsg); + ret = switch_disconnect(fpga->sw, dma, xsg); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, xsg, dma); + ret = switch_disconnect(fpga->sw, xsg, dma); if (ret) error("Failed to configure switch"); @@ -154,29 +163,28 @@ int fpga_test_xsg(struct fpga *f) if (ret) error("Failed to release DMA memory"); - return err > 1e-3; + cr_assert(err < 1e-3); } -int fpga_test_hls_dft(struct fpga *f) +Test(fpga, hls_dft, .description = "HLS: hls_dft") { int ret; struct ip *hls, *rtds; - rtds = ip_vlnv_lookup(&f->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); - hls = ip_vlnv_lookup(&f->ips, NULL, "hls", "hls_dft", NULL); + rtds = ip_vlnv_lookup(&fpga->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); + hls = ip_vlnv_lookup(&fpga->ips, NULL, "hls", "hls_dft", NULL); /* Check if required IP is available on FPGA */ - if (!hls || !rtds) - return -1; + cr_assert(hls && rtds); - ret = intc_enable(f->intc, (1 << rtds->irq), 0); + ret = intc_enable(fpga->intc, (1 << rtds->irq), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, rtds, hls); + ret = switch_connect(fpga->sw, rtds, hls); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, hls, rtds); + ret = switch_connect(fpga->sw, hls, rtds); if (ret) error("Failed to configure switch"); @@ -201,32 +209,29 @@ int fpga_test_hls_dft(struct fpga *f) } #endif - ret = switch_disconnect(f->sw, rtds, hls); + ret = switch_disconnect(fpga->sw, rtds, hls); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, hls, rtds); + ret = switch_disconnect(fpga->sw, hls, rtds); if (ret) error("Failed to configure switch"); - - return 0; } -int fpga_test_fifo(struct fpga *f) +Test(fpga, fifo, .description = "FIFO") { int ret; ssize_t len; char src[255], dst[255]; struct ip *fifo; - fifo = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_fifo_mm_s", NULL); - if (!fifo) - return -1; + fifo = ip_vlnv_lookup(&fpga->ips, "xilinx.com", "ip", "axi_fifo_mm_s", NULL); + cr_assert(fifo); - ret = intc_enable(f->intc, (1 << fifo->irq), 0); + ret = intc_enable(fpga->intc, (1 << fifo->irq), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, fifo, fifo); + ret = switch_connect(fpga->sw, fifo, fifo); if (ret) error("Failed to configure switch"); @@ -244,24 +249,24 @@ int fpga_test_fifo(struct fpga *f) if (len != sizeof(dst)) error("Failed to read from FIFO"); - ret = intc_disable(f->intc, (1 << fifo->irq)); + ret = intc_disable(fpga->intc, (1 << fifo->irq)); if (ret) error("Failed to disable interrupt"); - ret = switch_disconnect(f->sw, fifo, fifo); + ret = switch_disconnect(fpga->sw, fifo, fifo); if (ret) error("Failed to configure switch"); /* Compare data */ - return memcmp(src, dst, sizeof(src)); + cr_assert_eq(memcmp(src, dst, sizeof(src)), 0); } -int fpga_test_dma(struct fpga *f) +Test(fpga, dma, .description = "DMA") { int ret = -1; struct dma_mem mem, src, dst; - list_foreach(struct ip *dma, &f->ips) { INDENT + list_foreach(struct ip *dma, &fpga->ips) { INDENT if (!ip_vlnv_match(dma, "xilinx.com", "ip", "axi_dma", NULL)) continue; /* skip non DMA IP cores */ @@ -270,12 +275,10 @@ int fpga_test_dma(struct fpga *f) ssize_t len = dma->dma.inst.HasSg ? 64 << 20 : 1 << 2; ret = dma_alloc(dma, &mem, 2 * len, 0); - if (ret) - return -1; + cr_assert_eq(ret, 0); ret = dma_mem_split(&mem, &src, &dst); - if (ret) - return -1; + cr_assert_eq(ret, 0); /* Get new random data */ ret = read_random(src.base_virt, len); @@ -285,11 +288,11 @@ int fpga_test_dma(struct fpga *f) int irq_mm2s = dma->irq; int irq_s2mm = dma->irq + 1; - ret = intc_enable(f->intc, (1 << irq_mm2s) | (1 << irq_s2mm), 0); + ret = intc_enable(fpga->intc, (1 << irq_mm2s) | (1 << irq_s2mm), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, dma, dma); + ret = switch_connect(fpga->sw, dma, dma); if (ret) error("Failed to configure switch"); @@ -302,11 +305,11 @@ int fpga_test_dma(struct fpga *f) info("DMA %s (%s): %s", dma->name, dma->dma.inst.HasSg ? "scatter-gather" : "simple", ret ? RED("failed") : GRN("passed")); - ret = switch_disconnect(f->sw, dma, dma); + ret = switch_disconnect(fpga->sw, dma, dma); if (ret) error("Failed to configure switch"); - ret = intc_disable(f->intc, (1 << irq_mm2s) | (1 << irq_s2mm)); + ret = intc_disable(fpga->intc, (1 << irq_mm2s) | (1 << irq_s2mm)); if (ret) error("Failed to disable interrupt"); @@ -315,21 +318,20 @@ int fpga_test_dma(struct fpga *f) error("Failed to release DMA memory"); } - return ret; + cr_assert_eq(ret, 0); } -int fpga_test_timer(struct fpga *f) +Test(fpga, timer, .description = "Timer Counter") { int ret; struct ip *tmr; - tmr = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_timer", NULL); - if (!tmr) - return -1; + tmr = ip_vlnv_lookup(&fpga->ips, "xilinx.com", "ip", "axi_timer", NULL); + cr_assert(tmr); XTmrCtr *xtmr = &tmr->timer.inst; - ret = intc_enable(f->intc, (1 << tmr->irq), 0); + ret = intc_enable(fpga->intc, (1 << tmr->irq), 0); if (ret) error("Failed to enable interrupt"); @@ -337,22 +339,22 @@ int fpga_test_timer(struct fpga *f) XTmrCtr_SetResetValue(xtmr, 0, FPGA_AXI_HZ / 125); XTmrCtr_Start(xtmr, 0); - uint64_t counter = intc_wait(f->intc, tmr->irq); + uint64_t counter = intc_wait(fpga->intc, tmr->irq); info("Got IRQ: counter = %ju", counter); if (counter == 1) - return 0; + return; else warn("Counter was not 1"); - intc_disable(f->intc, (1 << tmr->irq)); + intc_disable(fpga->intc, (1 << tmr->irq)); if (ret) error("Failed to disable interrupt"); - return -1; + return; } -int fpga_test_rtds_rtt(struct fpga *f) +Test(fpga, rtds_rtt, .description = "RTDS: tight rtt") { int ret; struct ip *dma, *rtds; @@ -360,17 +362,16 @@ int fpga_test_rtds_rtt(struct fpga *f) size_t recvlen; /* Get IP cores */ - rtds = ip_vlnv_lookup(&f->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); - dma = list_lookup(&f->ips, "dma_1"); + rtds = ip_vlnv_lookup(&fpga->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); + dma = list_lookup(&fpga->ips, "dma_1"); /* Check if required IP is available on FPGA */ - if (!dma || !rtds) - return -1; + cr_assert (dma && rtds); - ret = switch_connect(f->sw, rtds, dma); + ret = switch_connect(fpga->sw, rtds, dma); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, dma, rtds); + ret = switch_connect(fpga->sw, dma, rtds); if (ret) error("Failed to configure switch"); @@ -397,16 +398,14 @@ int fpga_test_rtds_rtt(struct fpga *f) error("Failed to complete DMA write: %d", ret); } - ret = switch_disconnect(f->sw, rtds, dma); + ret = switch_disconnect(fpga->sw, rtds, dma); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, dma, rtds); + ret = switch_disconnect(fpga->sw, dma, rtds); if (ret) error("Failed to configure switch"); ret = dma_free(dma, &buf); if (ret) error("Failed to release DMA memory"); - - return 0; } \ No newline at end of file From f505e6cb7f88720935b62f5153f9ddcf714608d5 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 23 Dec 2016 18:12:48 +0100 Subject: [PATCH 059/211] added curilo functions to read / write files on libcurl compatible protocols --- include/villas/curlio.h | 19 ++ lib/curlio.c | 444 ++++++++++++++++++++++++++++++++++++++++ tests/curlio.c | 99 +++++++++ 3 files changed, 562 insertions(+) create mode 100644 include/villas/curlio.h create mode 100644 lib/curlio.c create mode 100644 tests/curlio.c diff --git a/include/villas/curlio.h b/include/villas/curlio.h new file mode 100644 index 000000000..f8fe08666 --- /dev/null +++ b/include/villas/curlio.h @@ -0,0 +1,19 @@ + +#ifndef _CURLIO_H_ +#define _CURLIO_H_ + +typedef struct fcurl_data URL_FILE; + +URL_FILE *url_fopen(const char *url, const char *operation); + +int url_fclose(URL_FILE *file); + +int url_feof(URL_FILE *file); + +size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file); + +char * url_fgets(char *ptr, size_t size, URL_FILE *file); + +void url_rewind(URL_FILE *file); + +#endif /* _CURLIO_H_ */ \ No newline at end of file diff --git a/lib/curlio.c b/lib/curlio.c new file mode 100644 index 000000000..8e8544f26 --- /dev/null +++ b/lib/curlio.c @@ -0,0 +1,444 @@ +/** libcurl based remote IO + * + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include "curlio.h" + +/***************************************************************************** + * + * This example source code introduces a c library buffered I/O interface to + * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(), + * rewind(). Supported functions have identical prototypes to their normal c + * lib namesakes and are preceaded by url_ . + * + * Using this code you can replace your program's fopen() with url_fopen() + * and fread() with url_fread() and it become possible to read remote streams + * instead of (only) local files. Local files (ie those that can be directly + * fopened) will drop back to using the underlying clib implementations + * + * See the main() function at the bottom that shows an app that retrives from a + * specified url using fgets() and fread() and saves as two output files. + * + * Copyright (c) 2003 Simtec Electronics + * + * Re-implemented by Vincent Sanders with extensive + * reference to original curl example code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This example requires libcurl 7.9.7 or later. + */ +/* + * implements an fopen() abstraction allowing reading from URLs + * + */ + +#include +#include +#ifndef WIN32 + #include +#endif +#include +#include + +#include + +enum fcurl_type_e { + CFTYPE_NONE = 0, + CFTYPE_FILE = 1, + CFTYPE_CURL = 2 +}; + +struct fcurl_data +{ + enum fcurl_type_e type; /**< Type of handle */ + union { + CURL *curl; + FILE *file; + } handle; /**< Handle */ + + char *buffer; /**< Buffer to store cached data*/ + size_t buffer_len; /**< Currently allocated buffers length */ + size_t buffer_pos; /**< End of data in buffer*/ + int still_running; /**< Is background url fetch still in progress */ +}; + +/* We use a global one for convenience */ +CURLM *multi_handle; + +/* libcurl calls this routine to get more data */ +static size_t write_callback(char *buffer, size_t size, size_t nitems, void *userp) +{ + char *newbuff; + size_t rembuff; + + URL_FILE *url = (URL_FILE *)userp; + size *= nitems; + + rembuff = url->buffer_len - url->buffer_pos; /* Remaining space in buffer */ + + if (size > rembuff) { + /* Not enough space in buffer */ + newbuff = realloc(url->buffer, url->buffer_len + (size - rembuff)); + if (newbuff == NULL) { + fprintf(stderr, "callback buffer grow failed\n"); + size = rembuff; + } + else { + /* Realloc succeeded increase buffer size*/ + url->buffer_len += size - rembuff; + url->buffer = newbuff; + } + } + + memcpy(&url->buffer[url->buffer_pos], buffer, size); + url->buffer_pos += size; + + return size; +} + +/* Use to attempt to fill the read buffer up to requested number of bytes */ +static int fill_buffer(URL_FILE *file, size_t want) +{ + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + struct timeval timeout; + int rc; + CURLMcode mc; /* curl_multi_fdset() return code */ + + /* Only attempt to fill buffer if transactions still running and buffer + * doesn't exceed required size already + */ + if ((!file->still_running) || (file->buffer_pos > want)) + return 0; + + /* Attempt to fill buffer */ + do { + int maxfd = -1; + long curl_timeo = -1; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + /* Set a suitable timeout to fail on */ + timeout.tv_sec = 60; /* 1 minute */ + timeout.tv_usec = 0; + + curl_multi_timeout(multi_handle, &curl_timeo); + if (curl_timeo >= 0) { + timeout.tv_sec = curl_timeo / 1000; + if (timeout.tv_sec > 1) + timeout.tv_sec = 1; + else + timeout.tv_usec = (curl_timeo % 1000) * 1000; + } + + /* Get file descriptors from the transfers */ + mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); + + if (mc != CURLM_OK) { + fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); + break; + } + + /* On success the value of maxfd is guaranteed to be >= -1. We call + * select(maxfd + 1, ...); specially in case of (maxfd == -1) there are + * no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- + * to sleep 100ms, which is the minimum suggested value in the + * curl_multi_fdset() doc. */ + + if (maxfd == -1) { +#ifdef _WIN32 + Sleep(100); + rc = 0; +#else + /* Portable sleep for platforms other than Windows. */ + struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ + rc = select(0, NULL, NULL, NULL, &wait); +#endif + } + else { + /* Note that on some platforms 'timeout' may be modified by select(). + If you need access to the original value save a copy beforehand. */ + rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); + } + + switch (rc) { + case -1: + /* Select error */ + break; + + case 0: + default: + /* Timeout or readable/writable sockets */ + curl_multi_perform(multi_handle, &file->still_running); + break; + } + } while(file->still_running && (file->buffer_pos < want)); + return 1; +} + +/* Use to remove want bytes from the front of a files buffer */ +static int use_buffer(URL_FILE *file, size_t want) +{ + /* Sort out buffer */ + if ((file->buffer_pos - want) <= 0) { + /* Ditch buffer - write will recreate */ + free(file->buffer); + file->buffer = NULL; + file->buffer_pos = 0; + file->buffer_len = 0; + } + else { + /* Move rest down make it available for later */ + memmove(file->buffer, &file->buffer[want], (file->buffer_pos - want)); + + file->buffer_pos -= want; + } + return 0; +} + +URL_FILE *url_fopen(const char *url, const char *operation) +{ + /* This code could check for URLs or types in the 'url' and + basically use the real fopen() for standard files */ + + URL_FILE *file; + (void)operation; + + file = malloc(sizeof(URL_FILE)); + if (!file) + return NULL; + + memset(file, 0, sizeof(URL_FILE)); + + file->handle.file = fopen(url, operation); + if (file->handle.file) + file->type = CFTYPE_FILE; /* Marked as standard file */ + else { + file->type = CFTYPE_CURL; /* Marked as URL */ + file->handle.curl = curl_easy_init(); + + curl_easy_setopt(file->handle.curl, CURLOPT_URL, url); + curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file); + curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback); + + if (!multi_handle) + multi_handle = curl_multi_init(); + + curl_multi_add_handle(multi_handle, file->handle.curl); + + /* Lets start the fetch */ + curl_multi_perform(multi_handle, &file->still_running); + + if ((file->buffer_pos == 0) && (!file->still_running)) { + /* If still_running is 0 now, we should return NULL */ + + /* Make sure the easy handle is not in the multi handle anymore */ + curl_multi_remove_handle(multi_handle, file->handle.curl); + + /* Cleanup */ + curl_easy_cleanup(file->handle.curl); + + free(file); + + file = NULL; + } + } + + return file; +} + +int url_fclose(URL_FILE *file) +{ + int ret = 0; /* Default is good return */ + + switch (file->type) { + case CFTYPE_FILE: + ret = fclose(file->handle.file); /* Passthrough */ + break; + + case CFTYPE_CURL: + /* Make sure the easy handle is not in the multi handle anymore */ + curl_multi_remove_handle(multi_handle, file->handle.curl); + + /* Cleanup */ + curl_easy_cleanup(file->handle.curl); + break; + + default: /* Unknown or supported type - oh dear */ + ret = EOF; + errno = EBADF; + break; + } + + free(file->buffer);/* Free any allocated buffer space */ + free(file); + + return ret; +} + +int url_feof(URL_FILE *file) +{ + int ret = 0; + + switch (file->type) { + case CFTYPE_FILE: + ret = feof(file->handle.file); + break; + + case CFTYPE_CURL: + if ((file->buffer_pos == 0) && (!file->still_running)) + ret = 1; + break; + + default: /* Unknown or supported type - oh dear */ + ret = -1; + errno = EBADF; + break; + } + + return ret; +} + +size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file) +{ + size_t want; + + switch (file->type) { + case CFTYPE_FILE: + want = fread(ptr, size, nmemb, file->handle.file); + break; + + case CFTYPE_CURL: + want = nmemb * size; + + fill_buffer(file, want); + + /* Check if theres data in the buffer - if not fill_buffer() + * either errored or EOF */ + if (!file->buffer_pos) + return 0; + + /* Ensure only available data is considered */ + if (file->buffer_pos < want) + want = file->buffer_pos; + + /* Xfer data to caller */ + memcpy(ptr, file->buffer, want); + + use_buffer(file, want); + + want = want / size; /* Number of items */ + break; + + default: /* Unknown or supported type - oh dear */ + want = 0; + errno = EBADF; + break; + } + + return want; +} + +char *url_fgets(char *ptr, size_t size, URL_FILE *file) +{ + size_t want = size - 1; /* Always need to leave room for zero termination */ + size_t loop; + + switch (file->type) { + case CFTYPE_FILE: + ptr = fgets(ptr, (int)size, file->handle.file); + break; + + case CFTYPE_CURL: + fill_buffer(file, want); + + /* Check if theres data in the buffer - if not fill either errored or + * EOF */ + if (!file->buffer_pos) + return NULL; + + /* Ensure only available data is considered */ + if (file->buffer_pos < want) + want = file->buffer_pos; + + /* Buffer contains data */ + /* Look for newline or eof */ + for (loop = 0; loop < want; loop++) { + if (file->buffer[loop] == '\n') { + want = loop+1; /* Include newline */ + break; + } + } + + /* Xfer data to caller */ + memcpy(ptr, file->buffer, want); + ptr[want] = 0; /* Allways null terminate */ + + use_buffer(file, want); + + break; + + default: /* Unknown or supported type - oh dear */ + ptr = NULL; + errno = EBADF; + break; + } + + return ptr;/*success */ +} + +void url_rewind(URL_FILE *file) +{ + switch (file->type) { + case CFTYPE_FILE: + rewind(file->handle.file); /* Passthrough */ + break; + + case CFTYPE_CURL: + /* Halt transaction */ + curl_multi_remove_handle(multi_handle, file->handle.curl); + + /* Restart */ + curl_multi_add_handle(multi_handle, file->handle.curl); + + /* Ditch buffer - write will recreate - resets stream pos */ + free(file->buffer); + file->buffer = NULL; + file->buffer_pos = 0; + file->buffer_len = 0; + + break; + + default: /* Unknown or supported type - oh dear */ + break; + } +} diff --git a/tests/curlio.c b/tests/curlio.c new file mode 100644 index 000000000..cd01b50c5 --- /dev/null +++ b/tests/curlio.c @@ -0,0 +1,99 @@ +#define FGETSFILE "fgets.test" +#define FREADFILE "fread.test" +#define REWINDFILE "rewind.test" + +/* Small main program to retrive from a url using fgets and fread saving the + * output to two test files (note the fgets method will corrupt binary files if + * they contain 0 chars */ +Test(curlio, main) +{ + URL_FILE *handle; + FILE *outf; + + size_t nread; + char buffer[256]; + const char *url; + + if(argc < 2) + url="http://192.168.7.3/testfile";/* default to testurl */ + else + url=argv[1];/* use passed url */ + + /* copy from url line by line with fgets */ + outf=fopen(FGETSFILE, "wb+"); + if(!outf) { + perror("couldn't open fgets output file\n"); + return 1; + } + + handle = url_fopen(url, "r"); + if(!handle) { + printf("couldn't url_fopen() %s\n", url); + fclose(outf); + return 2; + } + + while(!url_feof(handle)) { + url_fgets(buffer, sizeof(buffer), handle); + fwrite(buffer, 1, strlen(buffer), outf); + } + + url_fclose(handle); + + fclose(outf); + + + /* Copy from url with fread */ + outf=fopen(FREADFILE, "wb+"); + if(!outf) { + perror("couldn't open fread output file\n"); + return 1; + } + + handle = url_fopen("testfile", "r"); + if(!handle) { + printf("couldn't url_fopen() testfile\n"); + fclose(outf); + return 2; + } + + do { + nread = url_fread(buffer, 1, sizeof(buffer), handle); + fwrite(buffer, 1, nread, outf); + } while(nread); + + url_fclose(handle); + + fclose(outf); + + + /* Test rewind */ + outf=fopen(REWINDFILE, "wb+"); + if(!outf) { + perror("couldn't open fread output file\n"); + return 1; + } + + handle = url_fopen("testfile", "r"); + if(!handle) { + printf("couldn't url_fopen() testfile\n"); + fclose(outf); + return 2; + } + + nread = url_fread(buffer, 1, sizeof(buffer), handle); + fwrite(buffer, 1, nread, outf); + url_rewind(handle); + + buffer[0]='\n'; + fwrite(buffer, 1, 1, outf); + + nread = url_fread(buffer, 1, sizeof(buffer), handle); + fwrite(buffer, 1, nread, outf); + + url_fclose(handle); + + fclose(outf); + + return 0;/* all done */ +} \ No newline at end of file From 59816b37476357a8a6a9804c80d967a68f03ad64 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 19 Jan 2017 21:03:37 -0200 Subject: [PATCH 060/211] HTTP user-agent is now a project wide compile-time constant --- config.h | 2 ++ lib/nodes/ngsi.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config.h b/config.h index 087f7b3f9..b425ce9c2 100644 --- a/config.h +++ b/config.h @@ -37,6 +37,8 @@ #define SYSFS_PATH "/sys" #define PROCFS_PATH "/proc" +#define USER_AGENT "VILLASnode " VERSION + /* Required kernel version */ #define KERNEL_VERSION_MAJ 3 #define KERNEL_VERSION_MIN 6 diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index 747cd1b7a..4eb0c9ddd 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -475,13 +475,13 @@ int ngsi_open(struct node *n) if (i->tfd < 0) serror("Failed to create timer"); - i->headers = curl_slist_append(i->headers, "User-Agent: VILLASnode " VERSION); i->headers = curl_slist_append(i->headers, "Accept: application/json"); i->headers = curl_slist_append(i->headers, "Content-Type: application/json"); curl_easy_setopt(i->curl, CURLOPT_SSL_VERIFYPEER, i->ssl_verify); curl_easy_setopt(i->curl, CURLOPT_TIMEOUT_MS, i->timeout * 1e3); curl_easy_setopt(i->curl, CURLOPT_HTTPHEADER, i->headers); + curl_easy_setopt(i->curl, CURLOPT_USERAGENT, USER_AGENT); /* Create entity and atributes */ json_t *entity = ngsi_build_entity(i, NULL, 0, NGSI_ENTITY_METADATA); From 59af81284c9e8bf78437ad020b5a8e6dd0fc2efe Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 19 Jan 2017 23:12:52 -0200 Subject: [PATCH 061/211] Replaced curlio with own advio (advanced io) --- include/villas/advio.h | 36 ++++ include/villas/curlio.h | 19 -- lib/Makefile.inc | 4 +- lib/advio.c | 161 +++++++++++++++ lib/curlio.c | 444 ---------------------------------------- tests/advio.c | 69 +++++++ tests/curlio.c | 99 --------- 7 files changed, 268 insertions(+), 564 deletions(-) create mode 100644 include/villas/advio.h delete mode 100644 include/villas/curlio.h create mode 100644 lib/advio.c delete mode 100644 lib/curlio.c create mode 100644 tests/advio.c delete mode 100644 tests/curlio.c diff --git a/include/villas/advio.h b/include/villas/advio.h new file mode 100644 index 000000000..33435887f --- /dev/null +++ b/include/villas/advio.h @@ -0,0 +1,36 @@ +/** Advanced IO + * + */ + +#ifndef _ADVIO_H_ +#define _ADVIO_H_ + +#include + +#include + +struct advio { + CURL *curl; + FILE *file; + + const char *url; + + bool dirty; /**< The file contents have been modified. We need to upload */ +}; + +typedef struct advio AFILE; + +AFILE *afopen(const char *url, const char *mode); + +int afclose(AFILE *file); + +int afflush(AFILE *file); + +/* The remaining functions from stdio are just replaced macros */ + +#define afeof(af) feof(af->file) + +size_t afread(void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream); +size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream); + +#endif /* _ADVIO_H_ */ \ No newline at end of file diff --git a/include/villas/curlio.h b/include/villas/curlio.h deleted file mode 100644 index f8fe08666..000000000 --- a/include/villas/curlio.h +++ /dev/null @@ -1,19 +0,0 @@ - -#ifndef _CURLIO_H_ -#define _CURLIO_H_ - -typedef struct fcurl_data URL_FILE; - -URL_FILE *url_fopen(const char *url, const char *operation); - -int url_fclose(URL_FILE *file); - -int url_feof(URL_FILE *file); - -size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file); - -char * url_fgets(char *ptr, size_t size, URL_FILE *file); - -void url_rewind(URL_FILE *file); - -#endif /* _CURLIO_H_ */ \ No newline at end of file diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 03a8e32e1..787c62dba 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -4,9 +4,9 @@ LIBS = $(BUILDDIR)/libvillas.so # Object files for libvillas LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ - $(addprefix lib/, sample.c path.c node.c hooks.c \ + $(addprefix lib/, sample.c path.c node.c hooks.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ - queue.c memory.c \ + queue.c memory.c advio.c \ ) \ $(wildcard lib/hooks/*.c) \ diff --git a/lib/advio.c b/lib/advio.c new file mode 100644 index 000000000..9111db9e1 --- /dev/null +++ b/lib/advio.c @@ -0,0 +1,161 @@ +/** libcurl based remote IO + * + * Implements an fopen() abstraction allowing reading from URLs + * + * This file introduces a c library buffered I/O interface to + * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(), + * rewind(). Supported functions have identical prototypes to their normal c + * lib namesakes and are preceaded by a . + * + * Using this code you can replace your program's fopen() with afopen() + * and fread() with afread() and it become possible to read remote streams + * instead of (only) local files. Local files (ie those that can be directly + * fopened) will drop back to using the underlying clib implementations + * + * This example requires libcurl 7.9.7 or later. + * + * @author Steffen Vogel + * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#include "utils.h" +#include "config.h" +#include "advio.h" + +AFILE *afopen(const char *url, const char *mode) +{ + CURLcode res; + + AFILE *af = alloc(sizeof(AFILE)); + + af->file = tmpfile(); + if (!af->file) + goto out2; + + af->curl = curl_easy_init(); + if (!af->curl) + goto out1; + + curl_easy_setopt(af->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(af->curl, CURLOPT_USERAGENT, USER_AGENT); + curl_easy_setopt(af->curl, CURLOPT_URL, url); + curl_easy_setopt(af->curl, CURLOPT_WRITEDATA, af->file); + + res = curl_easy_perform(af->curl); + switch (res) { + case CURLE_OK: + switch (mode[0]) { + case 'w': + case 'r': + fseek(af->file, 0, SEEK_SET); + break; + + case 'a': + fseek(af->file, 0, SEEK_END); + break; + } + break; + + /* The following error codes indicate that the file does not exist + * Check the fopen mode to see if we should continue with an emoty file */ + case CURLE_FILE_COULDNT_READ_FILE: + case CURLE_TFTP_NOTFOUND: + case CURLE_REMOTE_FILE_NOT_FOUND: + if (mode[0] == 'a' || (mode[0] == 'w' && mode[1] == '+')) + break; /* its okay */ + + default: + goto out0; /* no please fail here */ + } + + af->url = strdup(url); + af->dirty = false; + + return af; + +out0: curl_easy_cleanup(af->curl); + + printf("Failed to download file (%d): %s\n", res, curl_easy_strerror(res)); + +out1: fclose(af->file); +out2: free(af); + + return NULL; +} + +int afclose(AFILE *af) +{ + int ret; + + ret = afflush(af); + + curl_easy_cleanup(af->curl); + + fclose(af->file); + + free(af); + + return ret; +} + +int afflush(AFILE *af) +{ + int ret; + + ret = fflush(af->file); + if (ret) + return ret; + + /* Only upload file if it was changed */ + if (af->dirty) { + CURLcode res; + long pos; + + /* Remember old stream pointer */ + pos = ftell(af->file); + fseek(af->file, 0, SEEK_SET); + + curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(af->curl, CURLOPT_READDATA, af->file); + + res = curl_easy_perform(af->curl); + + /* Restore old stream pointer */ + fseek(af->file, pos, SEEK_SET); + + if (res != CURLE_OK) + return -1; + + af->dirty = false; + } + + return 0; +} + +size_t afread(void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream) +{ + return fread(ptr, size, nitems, stream->file); +} + +size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream) +{ + size_t ret; + + ret = fwrite(ptr, size, nitems, stream->file); + + if (ret > 0) + stream->dirty = true; + + return ret; +} diff --git a/lib/curlio.c b/lib/curlio.c deleted file mode 100644 index 8e8544f26..000000000 --- a/lib/curlio.c +++ /dev/null @@ -1,444 +0,0 @@ -/** libcurl based remote IO - * - * @author Steffen Vogel - * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - *********************************************************************************/ - -#include "curlio.h" - -/***************************************************************************** - * - * This example source code introduces a c library buffered I/O interface to - * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(), - * rewind(). Supported functions have identical prototypes to their normal c - * lib namesakes and are preceaded by url_ . - * - * Using this code you can replace your program's fopen() with url_fopen() - * and fread() with url_fread() and it become possible to read remote streams - * instead of (only) local files. Local files (ie those that can be directly - * fopened) will drop back to using the underlying clib implementations - * - * See the main() function at the bottom that shows an app that retrives from a - * specified url using fgets() and fread() and saves as two output files. - * - * Copyright (c) 2003 Simtec Electronics - * - * Re-implemented by Vincent Sanders with extensive - * reference to original curl example code - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This example requires libcurl 7.9.7 or later. - */ -/* - * implements an fopen() abstraction allowing reading from URLs - * - */ - -#include -#include -#ifndef WIN32 - #include -#endif -#include -#include - -#include - -enum fcurl_type_e { - CFTYPE_NONE = 0, - CFTYPE_FILE = 1, - CFTYPE_CURL = 2 -}; - -struct fcurl_data -{ - enum fcurl_type_e type; /**< Type of handle */ - union { - CURL *curl; - FILE *file; - } handle; /**< Handle */ - - char *buffer; /**< Buffer to store cached data*/ - size_t buffer_len; /**< Currently allocated buffers length */ - size_t buffer_pos; /**< End of data in buffer*/ - int still_running; /**< Is background url fetch still in progress */ -}; - -/* We use a global one for convenience */ -CURLM *multi_handle; - -/* libcurl calls this routine to get more data */ -static size_t write_callback(char *buffer, size_t size, size_t nitems, void *userp) -{ - char *newbuff; - size_t rembuff; - - URL_FILE *url = (URL_FILE *)userp; - size *= nitems; - - rembuff = url->buffer_len - url->buffer_pos; /* Remaining space in buffer */ - - if (size > rembuff) { - /* Not enough space in buffer */ - newbuff = realloc(url->buffer, url->buffer_len + (size - rembuff)); - if (newbuff == NULL) { - fprintf(stderr, "callback buffer grow failed\n"); - size = rembuff; - } - else { - /* Realloc succeeded increase buffer size*/ - url->buffer_len += size - rembuff; - url->buffer = newbuff; - } - } - - memcpy(&url->buffer[url->buffer_pos], buffer, size); - url->buffer_pos += size; - - return size; -} - -/* Use to attempt to fill the read buffer up to requested number of bytes */ -static int fill_buffer(URL_FILE *file, size_t want) -{ - fd_set fdread; - fd_set fdwrite; - fd_set fdexcep; - struct timeval timeout; - int rc; - CURLMcode mc; /* curl_multi_fdset() return code */ - - /* Only attempt to fill buffer if transactions still running and buffer - * doesn't exceed required size already - */ - if ((!file->still_running) || (file->buffer_pos > want)) - return 0; - - /* Attempt to fill buffer */ - do { - int maxfd = -1; - long curl_timeo = -1; - - FD_ZERO(&fdread); - FD_ZERO(&fdwrite); - FD_ZERO(&fdexcep); - - /* Set a suitable timeout to fail on */ - timeout.tv_sec = 60; /* 1 minute */ - timeout.tv_usec = 0; - - curl_multi_timeout(multi_handle, &curl_timeo); - if (curl_timeo >= 0) { - timeout.tv_sec = curl_timeo / 1000; - if (timeout.tv_sec > 1) - timeout.tv_sec = 1; - else - timeout.tv_usec = (curl_timeo % 1000) * 1000; - } - - /* Get file descriptors from the transfers */ - mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); - - if (mc != CURLM_OK) { - fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); - break; - } - - /* On success the value of maxfd is guaranteed to be >= -1. We call - * select(maxfd + 1, ...); specially in case of (maxfd == -1) there are - * no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- - * to sleep 100ms, which is the minimum suggested value in the - * curl_multi_fdset() doc. */ - - if (maxfd == -1) { -#ifdef _WIN32 - Sleep(100); - rc = 0; -#else - /* Portable sleep for platforms other than Windows. */ - struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ - rc = select(0, NULL, NULL, NULL, &wait); -#endif - } - else { - /* Note that on some platforms 'timeout' may be modified by select(). - If you need access to the original value save a copy beforehand. */ - rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); - } - - switch (rc) { - case -1: - /* Select error */ - break; - - case 0: - default: - /* Timeout or readable/writable sockets */ - curl_multi_perform(multi_handle, &file->still_running); - break; - } - } while(file->still_running && (file->buffer_pos < want)); - return 1; -} - -/* Use to remove want bytes from the front of a files buffer */ -static int use_buffer(URL_FILE *file, size_t want) -{ - /* Sort out buffer */ - if ((file->buffer_pos - want) <= 0) { - /* Ditch buffer - write will recreate */ - free(file->buffer); - file->buffer = NULL; - file->buffer_pos = 0; - file->buffer_len = 0; - } - else { - /* Move rest down make it available for later */ - memmove(file->buffer, &file->buffer[want], (file->buffer_pos - want)); - - file->buffer_pos -= want; - } - return 0; -} - -URL_FILE *url_fopen(const char *url, const char *operation) -{ - /* This code could check for URLs or types in the 'url' and - basically use the real fopen() for standard files */ - - URL_FILE *file; - (void)operation; - - file = malloc(sizeof(URL_FILE)); - if (!file) - return NULL; - - memset(file, 0, sizeof(URL_FILE)); - - file->handle.file = fopen(url, operation); - if (file->handle.file) - file->type = CFTYPE_FILE; /* Marked as standard file */ - else { - file->type = CFTYPE_CURL; /* Marked as URL */ - file->handle.curl = curl_easy_init(); - - curl_easy_setopt(file->handle.curl, CURLOPT_URL, url); - curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file); - curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L); - curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback); - - if (!multi_handle) - multi_handle = curl_multi_init(); - - curl_multi_add_handle(multi_handle, file->handle.curl); - - /* Lets start the fetch */ - curl_multi_perform(multi_handle, &file->still_running); - - if ((file->buffer_pos == 0) && (!file->still_running)) { - /* If still_running is 0 now, we should return NULL */ - - /* Make sure the easy handle is not in the multi handle anymore */ - curl_multi_remove_handle(multi_handle, file->handle.curl); - - /* Cleanup */ - curl_easy_cleanup(file->handle.curl); - - free(file); - - file = NULL; - } - } - - return file; -} - -int url_fclose(URL_FILE *file) -{ - int ret = 0; /* Default is good return */ - - switch (file->type) { - case CFTYPE_FILE: - ret = fclose(file->handle.file); /* Passthrough */ - break; - - case CFTYPE_CURL: - /* Make sure the easy handle is not in the multi handle anymore */ - curl_multi_remove_handle(multi_handle, file->handle.curl); - - /* Cleanup */ - curl_easy_cleanup(file->handle.curl); - break; - - default: /* Unknown or supported type - oh dear */ - ret = EOF; - errno = EBADF; - break; - } - - free(file->buffer);/* Free any allocated buffer space */ - free(file); - - return ret; -} - -int url_feof(URL_FILE *file) -{ - int ret = 0; - - switch (file->type) { - case CFTYPE_FILE: - ret = feof(file->handle.file); - break; - - case CFTYPE_CURL: - if ((file->buffer_pos == 0) && (!file->still_running)) - ret = 1; - break; - - default: /* Unknown or supported type - oh dear */ - ret = -1; - errno = EBADF; - break; - } - - return ret; -} - -size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file) -{ - size_t want; - - switch (file->type) { - case CFTYPE_FILE: - want = fread(ptr, size, nmemb, file->handle.file); - break; - - case CFTYPE_CURL: - want = nmemb * size; - - fill_buffer(file, want); - - /* Check if theres data in the buffer - if not fill_buffer() - * either errored or EOF */ - if (!file->buffer_pos) - return 0; - - /* Ensure only available data is considered */ - if (file->buffer_pos < want) - want = file->buffer_pos; - - /* Xfer data to caller */ - memcpy(ptr, file->buffer, want); - - use_buffer(file, want); - - want = want / size; /* Number of items */ - break; - - default: /* Unknown or supported type - oh dear */ - want = 0; - errno = EBADF; - break; - } - - return want; -} - -char *url_fgets(char *ptr, size_t size, URL_FILE *file) -{ - size_t want = size - 1; /* Always need to leave room for zero termination */ - size_t loop; - - switch (file->type) { - case CFTYPE_FILE: - ptr = fgets(ptr, (int)size, file->handle.file); - break; - - case CFTYPE_CURL: - fill_buffer(file, want); - - /* Check if theres data in the buffer - if not fill either errored or - * EOF */ - if (!file->buffer_pos) - return NULL; - - /* Ensure only available data is considered */ - if (file->buffer_pos < want) - want = file->buffer_pos; - - /* Buffer contains data */ - /* Look for newline or eof */ - for (loop = 0; loop < want; loop++) { - if (file->buffer[loop] == '\n') { - want = loop+1; /* Include newline */ - break; - } - } - - /* Xfer data to caller */ - memcpy(ptr, file->buffer, want); - ptr[want] = 0; /* Allways null terminate */ - - use_buffer(file, want); - - break; - - default: /* Unknown or supported type - oh dear */ - ptr = NULL; - errno = EBADF; - break; - } - - return ptr;/*success */ -} - -void url_rewind(URL_FILE *file) -{ - switch (file->type) { - case CFTYPE_FILE: - rewind(file->handle.file); /* Passthrough */ - break; - - case CFTYPE_CURL: - /* Halt transaction */ - curl_multi_remove_handle(multi_handle, file->handle.curl); - - /* Restart */ - curl_multi_add_handle(multi_handle, file->handle.curl); - - /* Ditch buffer - write will recreate - resets stream pos */ - free(file->buffer); - file->buffer = NULL; - file->buffer_pos = 0; - file->buffer_len = 0; - - break; - - default: /* Unknown or supported type - oh dear */ - break; - } -} diff --git a/tests/advio.c b/tests/advio.c new file mode 100644 index 000000000..361a33e1f --- /dev/null +++ b/tests/advio.c @@ -0,0 +1,69 @@ +#include +#include + +#include + +#include +#include + +Test(advio, download) +{ + AFILE *af; + size_t len; + int ret; + char buffer[1024]; + + const char *url = "http://www.textfiles.com/100/angela.art"; + + af = afopen(url, "r"); + cr_assert(af, "Failed to download file"); + cr_log_info("Opened file %s", url); + + while (!afeof(af)) { + errno = 0; + len = afread(buffer, 1, sizeof(buffer), af); + cr_log_info("Read %zu bytes", len); + + fwrite(buffer, 1, len, stdout); + } + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close/upload file"); +} + +Test(advio, upload) +{ + AFILE *af; + size_t len1, len2; + int ret; + + const char *uri = "file:///tmp/test.txt"; + char rnd[128]; + char buffer[128]; + + /* Get some random bytes */ + FILE *r = fopen("/dev/urandom", "r"); + cr_assert(r); + + len1 = fread(rnd, 1, sizeof(rnd), r); + + /* Open file for writing */ + af = afopen(uri, "w+"); + cr_assert(af, "Failed to download file"); + + len2 = afwrite(rnd, 1, len1, af); + cr_assert_eq(len1, len2); + + ret = afclose(af); + cr_assert_eq(ret, 0, "Failed to close/upload file"); + + /* Open for reading and comparison */ + af = afopen(uri, "r"); + cr_assert(af, "Failed to download file"); + + len2 = afread(buffer, 1, len1, af); + cr_assert_arr_eq(rnd, buffer, len2); + + ret = afclose(af); + cr_assert(ret == 0, "Failed to close file"); +} \ No newline at end of file diff --git a/tests/curlio.c b/tests/curlio.c deleted file mode 100644 index cd01b50c5..000000000 --- a/tests/curlio.c +++ /dev/null @@ -1,99 +0,0 @@ -#define FGETSFILE "fgets.test" -#define FREADFILE "fread.test" -#define REWINDFILE "rewind.test" - -/* Small main program to retrive from a url using fgets and fread saving the - * output to two test files (note the fgets method will corrupt binary files if - * they contain 0 chars */ -Test(curlio, main) -{ - URL_FILE *handle; - FILE *outf; - - size_t nread; - char buffer[256]; - const char *url; - - if(argc < 2) - url="http://192.168.7.3/testfile";/* default to testurl */ - else - url=argv[1];/* use passed url */ - - /* copy from url line by line with fgets */ - outf=fopen(FGETSFILE, "wb+"); - if(!outf) { - perror("couldn't open fgets output file\n"); - return 1; - } - - handle = url_fopen(url, "r"); - if(!handle) { - printf("couldn't url_fopen() %s\n", url); - fclose(outf); - return 2; - } - - while(!url_feof(handle)) { - url_fgets(buffer, sizeof(buffer), handle); - fwrite(buffer, 1, strlen(buffer), outf); - } - - url_fclose(handle); - - fclose(outf); - - - /* Copy from url with fread */ - outf=fopen(FREADFILE, "wb+"); - if(!outf) { - perror("couldn't open fread output file\n"); - return 1; - } - - handle = url_fopen("testfile", "r"); - if(!handle) { - printf("couldn't url_fopen() testfile\n"); - fclose(outf); - return 2; - } - - do { - nread = url_fread(buffer, 1, sizeof(buffer), handle); - fwrite(buffer, 1, nread, outf); - } while(nread); - - url_fclose(handle); - - fclose(outf); - - - /* Test rewind */ - outf=fopen(REWINDFILE, "wb+"); - if(!outf) { - perror("couldn't open fread output file\n"); - return 1; - } - - handle = url_fopen("testfile", "r"); - if(!handle) { - printf("couldn't url_fopen() testfile\n"); - fclose(outf); - return 2; - } - - nread = url_fread(buffer, 1, sizeof(buffer), handle); - fwrite(buffer, 1, nread, outf); - url_rewind(handle); - - buffer[0]='\n'; - fwrite(buffer, 1, 1, outf); - - nread = url_fread(buffer, 1, sizeof(buffer), handle); - fwrite(buffer, 1, nread, outf); - - url_fclose(handle); - - fclose(outf); - - return 0;/* all done */ -} \ No newline at end of file From e7bf4e3f03f557f80f4c0b9d871124fb86d70468 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:04:22 -0300 Subject: [PATCH 062/211] fix header include guard macros include full name --- include/villas/fpga/dft.h | 6 +++--- include/villas/fpga/dma.h | 6 +++--- include/villas/fpga/fifo.h | 6 +++--- include/villas/fpga/intc.h | 6 +++--- include/villas/fpga/ip.h | 6 +++--- include/villas/fpga/model.h | 6 +++--- include/villas/fpga/rtds_axis.h | 6 +++--- include/villas/fpga/switch.h | 6 +++--- include/villas/fpga/timer.h | 6 +++--- include/villas/kernel/if.h | 6 +++--- include/villas/kernel/kernel.h | 6 +++--- include/villas/kernel/nl.h | 6 +++--- include/villas/kernel/pci.h | 6 +++--- include/villas/kernel/rt.h | 6 +++--- include/villas/kernel/tc.h | 4 ++-- include/villas/kernel/vfio.h | 6 +++--- include/villas/nodes/cbuilder.h | 13 +++++++++---- include/villas/nodes/file.h | 6 +++--- include/villas/nodes/fpga.h | 8 ++++---- include/villas/nodes/ngsi.h | 6 +++--- include/villas/nodes/opal.h | 6 +++--- include/villas/nodes/socket.h | 6 +++--- include/villas/nodes/websocket.h | 6 +++--- 23 files changed, 75 insertions(+), 70 deletions(-) diff --git a/include/villas/fpga/dft.h b/include/villas/fpga/dft.h index 017117c99..52edfb37b 100644 --- a/include/villas/fpga/dft.h +++ b/include/villas/fpga/dft.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _DFT_H_ -#define _DFT_H_ +#ifndef _FPGA_DFT_H_ +#define _FPGA_DFT_H_ #include @@ -31,4 +31,4 @@ int dft_init(struct ip *c); void dft_destroy(struct ip *c); -#endif /* _DFT_H_ */ \ No newline at end of file +#endif /* _FPGA_DFT_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/dma.h b/include/villas/fpga/dma.h index 1d3a215e1..172d80dba 100644 --- a/include/villas/fpga/dma.h +++ b/include/villas/fpga/dma.h @@ -9,8 +9,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _DMA_H_ -#define _DMA_H_ +#ifndef _FPGA_DMA_H_ +#define _FPGA_DMA_H_ #include #include @@ -65,4 +65,4 @@ int dma_ping_pong(struct ip *c, char *src, char *dst, size_t len); int dma_init(struct ip *c); -#endif /* _DMA_H_ */ \ No newline at end of file +#endif /* _FPGA_DMA_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/fifo.h b/include/villas/fpga/fifo.h index 597cd9a04..1872fa488 100644 --- a/include/villas/fpga/fifo.h +++ b/include/villas/fpga/fifo.h @@ -9,8 +9,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _FIFO_H_ -#define _FIFO_H_ +#ifndef _FPGA_FIFO_H_ +#define _FPGA_FIFO_H_ #include @@ -32,4 +32,4 @@ ssize_t fifo_write(struct ip *c, char *buf, size_t len); ssize_t fifo_read(struct ip *c, char *buf, size_t len); -#endif /* _FIFO_H_ */ \ No newline at end of file +#endif /* _FPGA_FIFO_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/intc.h b/include/villas/fpga/intc.h index da08afcd7..626fe07d6 100644 --- a/include/villas/fpga/intc.h +++ b/include/villas/fpga/intc.h @@ -6,8 +6,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _INTC_H_ -#define _INTC_H_ +#ifndef _FPGA_INTC_H_ +#define _FPGA_INTC_H_ #include @@ -35,4 +35,4 @@ int intc_disable(struct ip *c, uint32_t mask); uint64_t intc_wait(struct ip *c, int irq); -#endif /* _INTC_H_ */ \ No newline at end of file +#endif /* _FPGA_INTC_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index a573709c1..c3d2570aa 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -1,5 +1,5 @@ -#ifndef _IP_H_ -#define _IP_H_ +#ifndef _FPGA_IP_H_ +#define _FPGA_IP_H_ #include @@ -98,4 +98,4 @@ int ip_reset(struct ip *c); int ip_parse(struct ip *c, config_setting_t *cfg); -#endif \ No newline at end of file +#endif /* _FPGA_IP_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/model.h b/include/villas/fpga/model.h index f4269046c..5270d626a 100644 --- a/include/villas/fpga/model.h +++ b/include/villas/fpga/model.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _MODEL_H_ -#define _MODEL_H_ +#ifndef _FPGA_MODEL_H_ +#define _FPGA_MODEL_H_ #include #include @@ -123,4 +123,4 @@ int model_param_write(struct model_param *p, double v); int model_param_update(struct model_param *p, struct model_param *u); -#endif /* _MODEL_H_ */ \ No newline at end of file +#endif /* _FPGA_MODEL_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/rtds_axis.h b/include/villas/fpga/rtds_axis.h index 85bf10f32..ecd6072fc 100644 --- a/include/villas/fpga/rtds_axis.h +++ b/include/villas/fpga/rtds_axis.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _RTDS_AXIS_H_ -#define _RTDS_AXIS_H_ +#ifndef _FPGA_RTDS_AXIS_H_ +#define _FPGA_RTDS_AXIS_H_ /* Forward declaration */ struct ip; @@ -42,4 +42,4 @@ void rtds_axis_dump(struct ip *c); double rtds_axis_dt(struct ip *c); -#endif /* _RTDS_AXIS_H_ */ \ No newline at end of file +#endif /* _FPGA_RTDS_AXIS_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/switch.h b/include/villas/fpga/switch.h index dd2a9b8ac..fe109ad83 100644 --- a/include/villas/fpga/switch.h +++ b/include/villas/fpga/switch.h @@ -9,8 +9,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _SWITCH_H_ -#define _SWITCH_H_ +#ifndef _FPGA_SWITCH_H_ +#define _FPGA_SWITCH_H_ #include @@ -46,4 +46,4 @@ int switch_connect(struct ip *c, struct ip *mi, struct ip *si); int switch_disconnect(struct ip *c, struct ip *mi, struct ip *si); -#endif /* _SWITCH_H_ */ \ No newline at end of file +#endif /* _FPGA_SWITCH_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/timer.h b/include/villas/fpga/timer.h index b818c0058..27cc37b98 100644 --- a/include/villas/fpga/timer.h +++ b/include/villas/fpga/timer.h @@ -9,11 +9,11 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _TIMER_H_ -#define _TIMER_H_ +#ifndef _FPGA_TIMER_H_ +#define _FPGA_TIMER_H_ struct timer { XTmrCtr inst; }; -#endif \ No newline at end of file +#endif /* _FPGA_TIMER_H_ */ \ No newline at end of file diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h index 3d676694b..6099b0280 100644 --- a/include/villas/kernel/if.h +++ b/include/villas/kernel/if.h @@ -10,8 +10,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _IF_H_ -#define _IF_H_ +#ifndef _KERNEL_IF_H_ +#define _KERNEL_IF_H_ #include #include @@ -106,4 +106,4 @@ int if_get_irqs(struct interface *i); */ int if_set_affinity(struct interface *i, int affinity); -#endif /* _IF_H_ */ +#endif /* _KERNEL_IF_H_ */ diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index 10e750468..86d99406d 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _LINUX_H_ -#define _LINUX_H_ +#ifndef _KERNEL_KERNEL_H_ +#define _KERNEL_KERNEL_H_ #include @@ -69,4 +69,4 @@ int kernel_get_cacheline_size(); /** Set SMP affinity of IRQ */ int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); -#endif /* _LINUX_H_ */ +#endif /* _KERNEL_KERNEL_H_ */ diff --git a/include/villas/kernel/nl.h b/include/villas/kernel/nl.h index 6e1fb055e..1e7593626 100644 --- a/include/villas/kernel/nl.h +++ b/include/villas/kernel/nl.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _NL_H_ -#define _NL_H_ +#ifndef _KERNEL_NL_H_ +#define _KERNEL_NL_H_ #include #include @@ -27,4 +27,4 @@ struct nl_sock * nl_init(); /** Close and free global netlink socket. */ void nl_shutdown(); -#endif /* _NL_H_ */ \ No newline at end of file +#endif /* _KERNEL_NL_H_ */ \ No newline at end of file diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h index 747f5c488..acb0bab39 100644 --- a/include/villas/kernel/pci.h +++ b/include/villas/kernel/pci.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _PCI_H_ -#define _PCI_H_ +#ifndef _KERNEL_PCI_H_ +#define _KERNEL_PCI_H_ #include "list.h" @@ -64,4 +64,4 @@ int pci_attach_driver(struct pci_dev *d, const char *driver); /** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */ int pci_get_iommu_group(struct pci_dev *d); -#endif /* _PCI_H_ */ \ No newline at end of file +#endif /* _KERNEL_PCI_H_ */ \ No newline at end of file diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index 0c0f833cd..dc6d0ae77 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -7,9 +7,9 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _RT_H_ -#define _RT_H_ +#ifndef _KERNEL_RT_H_ +#define _KERNEL_RT_H_ int rt_init(int affinity, int priority); -#endif /* _RT_H_ */ \ No newline at end of file +#endif /* _KERNEL_RT_H_ */ \ No newline at end of file diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h index 973da527b..147e7dc80 100644 --- a/include/villas/kernel/tc.h +++ b/include/villas/kernel/tc.h @@ -12,8 +12,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _TC_H_ -#define _TC_H_ +#ifndef _KERNEL_TC_H_ +#define _KERNEL_TC_H_ #include diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 7f1a227aa..928f518cb 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -7,8 +7,8 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _VFIO_H_ -#define _VFIO_H_ +#ifndef _KERNEL_VFIO_H_ +#define _KERNEL_VFIO_H_ #include #include @@ -110,4 +110,4 @@ int vfio_unmap_dma(struct vfio_container *c, struct dma_mem *mem); /** munmap() a region which has been mapped by vfio_map_region() */ int vfio_unmap_region(struct vfio_dev *d, int idx); -#endif /* _VFIO_H_ */ +#endif /* _KERNEL_VFIO_H_ */ diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index 8fdf3296c..57b36a268 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -5,10 +5,15 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup cbuilder RTDS CBuilder model node + * @ingroup node + * @{ + *********************************************************************************/ -#ifndef _CBUILDER_H_ -#define _CBUILDER_H_ +#ifndef _NODES_CBUILDER_H_ +#define _NODES_CBUILDER_H_ #include @@ -52,4 +57,4 @@ struct cbmodel { int (*write)(float outputs[], int len); }; -#endif /* _CBUILDER_H_ */ \ No newline at end of file +#endif /** _NODES_CBUILDER_H_ @} */ \ No newline at end of file diff --git a/include/villas/nodes/file.h b/include/villas/nodes/file.h index 3eba00fa6..70e0e5e7b 100644 --- a/include/villas/nodes/file.h +++ b/include/villas/nodes/file.h @@ -15,8 +15,8 @@ *********************************************************************************/ -#ifndef _FILE_H_ -#define _FILE_H_ +#ifndef _NODES_FILE_H_ +#define _NODES_FILE_H_ #include "node.h" @@ -73,4 +73,4 @@ int file_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int file_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _FILE_H_ @} */ +#endif /** _NODES_FILE_H_ @} */ diff --git a/include/villas/nodes/fpga.h b/include/villas/nodes/fpga.h index 0dadcfd94..752d0b57c 100644 --- a/include/villas/nodes/fpga.h +++ b/include/villas/nodes/fpga.h @@ -9,13 +9,13 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. */ /** - * @addtogroup fpga VILLASnode + * @addtogroup fpga VILLASfpga * @ingroup node * @{ *********************************************************************************/ -#ifndef _FPGA_H_ -#define _FPGA_H_ +#ifndef _NODES_FPGA_H_ +#define _NODES_FPGA_H_ #include "kernel/vfio.h" #include "kernel/pci.h" @@ -101,4 +101,4 @@ int fpga_reset(struct fpga *f); /** Dump some details about the fpga card */ void fpga_dump(struct fpga *f); -#endif /** _FPGA_H_ @} */ +#endif /** _NODES_FPGA_H_ @} */ diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index 807904a87..f40b5a257 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -18,8 +18,8 @@ * @{ **********************************************************************************/ -#ifndef _NGSI_H_ -#define _NGSI_H_ +#ifndef _NODES_NGSI_H_ +#define _NODES_NGSI_H_ #include #include @@ -81,4 +81,4 @@ int ngsi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NGSI_H_ @} */ \ No newline at end of file +#endif /** _NODES_NGSI_H_ @} */ \ No newline at end of file diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index 9ae48de9d..dd3a5b704 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -14,8 +14,8 @@ * @{ **********************************************************************************/ -#ifndef _OPAL_H_ -#define _OPAL_H_ +#ifndef _NODES_OPAL_H_ +#define _NODES_OPAL_H_ #include @@ -73,4 +73,4 @@ int opal_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int opal_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _OPAL_H_ @} */ +#endif /** _NODES_OPAL_H_ @} */ diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 9f5cc7750..00a80d7b9 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -14,8 +14,8 @@ * @{ *********************************************************************************/ -#ifndef _SOCKET_H_ -#define _SOCKET_H_ +#ifndef _NODES_SOCKET_H_ +#define _NODES_SOCKET_H_ #include #include @@ -109,4 +109,4 @@ char * socket_print_addr(struct sockaddr *saddr); */ int socket_parse_addr(const char *str, struct sockaddr *sa, enum socket_layer layer, int flags); -#endif /** _SOCKET_H_ @} */ +#endif /** _NODES_SOCKET_H_ @} */ diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 4f3149534..a0bacdcc2 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -16,8 +16,8 @@ *********************************************************************************/ -#ifndef _WEBSOCKET_H_ -#define _WEBSOCKET_H_ +#ifndef _NODES_WEBSOCKET_H_ +#define _NODES_WEBSOCKET_H_ #include "node.h" #include "pool.h" @@ -84,4 +84,4 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _WEBSOCKET_H_ @} */ \ No newline at end of file +#endif /** _NODES_WEBSOCKET_H_ @} */ \ No newline at end of file From 84ebfda4e1bb20ab0473b417807a94d21cc24a06 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:12:35 -0300 Subject: [PATCH 063/211] refactored log faciltity macros --- include/villas/log.h | 31 +++++++++++++++++-------------- lib/hooks.c | 2 +- lib/kernel/if.c | 6 +++--- lib/memory.c | 6 +++--- lib/nodes/ngsi.c | 6 +++--- lib/nodes/opal.c | 14 +++++++------- lib/nodes/socket.c | 12 ++++++------ lib/path.c | 6 +++--- lib/pool.c | 2 +- 9 files changed, 44 insertions(+), 41 deletions(-) diff --git a/include/villas/log.h b/include/villas/log.h index c57d686bf..dbd7bda46 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -32,22 +32,25 @@ * * To be or-ed with the debug level */ -enum debug_facilities { - DBG_POOL = (1 << 8), - DBG_QUEUE = (1 << 9), - DBG_CONFIG = (1 << 10), - DBG_HOOK = (1 << 11), - DBG_PATH = (1 << 12), - DBG_MEM = (1 << 13), +enum log_facilities { + LOG_POOL = (1 << 8), + LOG_QUEUE = (1 << 9), + LOG_CONFIG = (1 << 10), + LOG_HOOK = (1 << 11), + LOG_PATH = (1 << 12), + LOG_MEM = (1 << 13), /* Node-types */ - DBG_SOCKET = (1 << 16), - DBG_FILE = (1 << 17), - DBG_FPGA = (1 << 18), - DBG_NGSI = (1 << 19), - DBG_WEBSOCKET = (1 << 20), - DBG_OPAL = (1 << 21), - DBG_NODE = (0xFF << 16) + LOG_SOCKET = (1 << 16), + LOG_FILE = (1 << 17), + LOG_FPGA = (1 << 18), + LOG_NGSI = (1 << 19), + LOG_WEBSOCKET = (1 << 20), + LOG_OPAL = (1 << 21), + + /* Classes */ + LOG_NODE = (0xFF << 16), + LOG_ALL = ~0xFF }; /** Change log indention for current thread. diff --git a/lib/hooks.c b/lib/hooks.c index ea4745e80..2e88e2813 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -42,7 +42,7 @@ int hook_run(struct path *p, struct sample *smps[], size_t cnt, int when) { list_foreach(struct hook *h, &p->hooks) { if (h->type & when) { - debug(DBG_HOOK | 22, "Running hook when=%u '%s' prio=%u, cnt=%zu", when, h->name, h->priority, cnt); + debug(LOG_HOOK | 22, "Running hook when=%u '%s' prio=%u, cnt=%zu", when, h->name, h->priority, cnt); cnt = h->cb(p, h, when, smps, cnt); if (cnt == 0) diff --git a/lib/kernel/if.c b/lib/kernel/if.c index 3a859304c..767831992 100644 --- a/lib/kernel/if.c +++ b/lib/kernel/if.c @@ -31,7 +31,7 @@ struct interface * if_create(struct rtnl_link *link) i->nl_link = link; - debug(DBG_SOCKET | 3, "Created interface '%s'", rtnl_link_get_name(i->nl_link)); + debug(LOG_SOCKET | 3, "Created interface '%s'", rtnl_link_get_name(i->nl_link)); int n = if_get_irqs(i); if (n > 0) @@ -94,7 +94,7 @@ int if_start(struct interface *i, int affinity) error("Failed to setup FW mark classifier: %s", nl_geterror(ret)); char *buf = tc_print(s->tc_qdisc); - debug(DBG_SOCKET | 5, "Starting network emulation on interface '%s' for FW mark %u: %s", + debug(LOG_SOCKET | 5, "Starting network emulation on interface '%s' for FW mark %u: %s", rtnl_link_get_name(i->nl_link), s->mark, buf); free(buf); @@ -195,7 +195,7 @@ int if_set_affinity(struct interface *i, int affinity) error("Failed to set affinity for IRQ %u", i->irqs[n]); fclose(file); - debug(DBG_SOCKET | 5, "Set affinity of IRQ %u for interface '%s' to %#x", i->irqs[n], rtnl_link_get_name(i->nl_link), affinity); + debug(LOG_SOCKET | 5, "Set affinity of IRQ %u for interface '%s' to %#x", i->irqs[n], rtnl_link_get_name(i->nl_link), affinity); } else error("Failed to set affinity for interface '%s'", rtnl_link_get_name(i->nl_link)); diff --git a/lib/memory.c b/lib/memory.c index 2f46161b3..da16d54d1 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -19,20 +19,20 @@ void * memory_alloc(const struct memtype *m, size_t len) { - debug(DBG_MEM | 2, "Allocating %#zx bytes of %s memory", len, m->name); + debug(LOG_MEM | 2, "Allocating %#zx bytes of %s memory", len, m->name); return m->alloc(len); } void * memory_alloc_aligned(const struct memtype *m, size_t len, size_t alignment) { - debug(DBG_MEM | 2, "Allocating %#zx bytes of %#zx-byte-aligned %s memory", len, alignment, m->name); + debug(LOG_MEM | 2, "Allocating %#zx bytes of %#zx-byte-aligned %s memory", len, alignment, m->name); warn("%s: not implemented yet!", __FUNCTION__); return memory_alloc(m, len); } int memory_free(const struct memtype *m, void *ptr, size_t len) { - debug(DBG_MEM | 2, "Releasing %#zx bytes of %s memory", len, m->name); + debug(LOG_MEM | 2, "Releasing %#zx bytes of %s memory", len, m->name); return m->free(ptr, len); } diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index 4eb0c9ddd..48f2abb2b 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -287,7 +287,7 @@ static int ngsi_request(CURL *handle, const char *endpoint, const char *operatio curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, strlen(post)); curl_easy_setopt(handle, CURLOPT_POSTFIELDS, post); - debug(DBG_NGSI | 18, "Request to context broker: %s\n%s", url, post); + debug(LOG_NGSI | 18, "Request to context broker: %s\n%s", url, post); /* We don't want to leave the handle in an invalid state */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old); @@ -301,8 +301,8 @@ static int ngsi_request(CURL *handle, const char *endpoint, const char *operatio curl_easy_getinfo(handle, CURLINFO_TOTAL_TIME, &time); - debug(DBG_NGSI | 16, "Request to context broker completed in %.4f seconds", time); - debug(DBG_NGSI | 17, "Response from context broker:\n%s", chunk.data); + debug(LOG_NGSI | 16, "Request to context broker completed in %.4f seconds", time); + debug(LOG_NGSI | 17, "Response from context broker:\n%s", chunk.data); *response = json_loads(chunk.data, 0, &err); if (!*response) diff --git a/lib/nodes/opal.c b/lib/nodes/opal.c index 86b891faf..396224743 100644 --- a/lib/nodes/opal.c +++ b/lib/nodes/opal.c @@ -88,7 +88,7 @@ int opal_deinit() if (err != EOK) error("Failed to close shared memory area (%d)", err); - debug(DBG_OPAL | 4, "Closing OPAL shared memory mapping"); + debug(LOG_OPAL | 4, "Closing OPAL shared memory mapping"); err = OpalSystemCtrl_UnRegister(print_shmem_name); if (err != EOK) @@ -104,7 +104,7 @@ int opal_deinit() int opal_print_global() { - debug(DBG_OPAL | 2, "Controller ID: %u", params.controllerID); + debug(LOG_OPAL | 2, "Controller ID: %u", params.controllerID); char *sbuf = alloc(send_icons * 5); char *rbuf = alloc(recv_icons * 5); @@ -114,17 +114,17 @@ int opal_print_global() for (int i = 0; i < recv_icons; i++) strcatf(&rbuf, "%u ", recv_ids[i]); - debug(DBG_OPAL | 2, "Send Blocks: %s", sbuf); - debug(DBG_OPAL | 2, "Receive Blocks: %s", rbuf); + debug(LOG_OPAL | 2, "Send Blocks: %s", sbuf); + debug(LOG_OPAL | 2, "Receive Blocks: %s", rbuf); free(sbuf); free(rbuf); - debug(DBG_OPAL | 2, "Control Block Parameters:"); + debug(LOG_OPAL | 2, "Control Block Parameters:"); for (int i = 0; i < GENASYNC_NB_FLOAT_PARAM; i++) - debug(DBG_OPAL | 2, "FloatParam[]%u] = %f", i, params.FloatParam[i]); + debug(LOG_OPAL | 2, "FloatParam[]%u] = %f", i, params.FloatParam[i]); for (int i = 0; i < GENASYNC_NB_STRING_PARAM; i++) - debug(DBG_OPAL | 2, "StringParam[%u] = %s", i, params.StringParam[i]); + debug(LOG_OPAL | 2, "StringParam[%u] = %s", i, params.StringParam[i]); return 0; } diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 000fc123a..14771e6f8 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -165,7 +165,7 @@ int socket_open(struct node *n) if (ret) serror("Failed to set FW mark for outgoing packets"); else - debug(DBG_SOCKET | 4, "Set FW mark for socket (sd=%u) to %u", s->sd, s->mark); + debug(LOG_SOCKET | 4, "Set FW mark for socket (sd=%u) to %u", s->sd, s->mark); } /* Set socket priority, QoS or TOS IP options */ @@ -177,7 +177,7 @@ int socket_open(struct node *n) if (setsockopt(s->sd, IPPROTO_IP, IP_TOS, &prio, sizeof(prio))) serror("Failed to set type of service (QoS)"); else - debug(DBG_SOCKET | 4, "Set QoS/TOS IP option for node %s to %#x", node_name(n), prio); + debug(LOG_SOCKET | 4, "Set QoS/TOS IP option for node %s to %#x", node_name(n), prio); break; default: @@ -185,7 +185,7 @@ int socket_open(struct node *n) if (setsockopt(s->sd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) serror("Failed to set socket priority"); else - debug(DBG_SOCKET | 4, "Set socket priority for node %s to %d", node_name(n), prio); + debug(LOG_SOCKET | 4, "Set socket priority for node %s to %d", node_name(n), prio); break; } @@ -388,7 +388,7 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt) } } - debug(DBG_SOCKET | 17, "Received message of %zd bytes: %u samples", bytes, received); + debug(LOG_SOCKET | 17, "Received message of %zd bytes: %u samples", bytes, received); return received; } @@ -430,7 +430,7 @@ int socket_write(struct node *n, struct sample *smps[], unsigned cnt) sent++; - debug(DBG_SOCKET | 17, "Sent packet of %zd bytes with 1 sample", bytes); + debug(LOG_SOCKET | 17, "Sent packet of %zd bytes with 1 sample", bytes); } } else { @@ -464,7 +464,7 @@ int socket_write(struct node *n, struct sample *smps[], unsigned cnt) sent = cnt; /** @todo Find better way to determine how many values we actually sent */ - debug(DBG_SOCKET | 17, "Sent packet of %zd bytes with %u samples", bytes, cnt); + debug(LOG_SOCKET | 17, "Sent packet of %zd bytes with %u samples", bytes, cnt); } return sent; diff --git a/lib/path.c b/lib/path.c index 69667cbcc..a1693f2b1 100644 --- a/lib/path.c +++ b/lib/path.c @@ -43,7 +43,7 @@ static void path_write(struct path *p, bool resend) else if (sent < tosend) warn("Partial write to node %s", node_name(n)); - debug(DBG_PATH | 15, "Sent %u messages to node %s", sent, node_name(n)); + debug(LOG_PATH | 15, "Sent %u messages to node %s", sent, node_name(n)); released = pool_put_many(&p->pool, (void **) smps, sent); if (sent != released) @@ -99,7 +99,7 @@ static void * path_run(void *arg) else if (recv < ready) warn("Partial read for path %s: read=%u expected=%u", path_name(p), recv, ready); - debug(DBG_PATH | 15, "Received %u messages from node %s", recv, node_name(p->in)); + debug(LOG_PATH | 15, "Received %u messages from node %s", recv, node_name(p->in)); /* Run preprocessing hooks for vector of samples */ enqueue = hook_run(p, smps, recv, HOOK_READ); @@ -114,7 +114,7 @@ static void * path_run(void *arg) ready -= enqueued; - debug(DBG_PATH | 3, "Enqueuing %u samples to queue of path %s", enqueue, path_name(p)); + debug(LOG_PATH | 3, "Enqueuing %u samples to queue of path %s", enqueue, path_name(p)); /* At fixed rate mode, messages are send by another (asynchronous) thread */ if (p->rate == 0) diff --git a/lib/pool.c b/lib/pool.c index 955b8b77a..d84f24c81 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -26,7 +26,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, const struct memtype * if (!p->buffer) serror("Failed to allocate memory for memory pool"); else - debug(DBG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); + debug(LOG_POOL | 4, "Allocated %#zx bytes for memory pool", p->len); ret = queue_init(&p->queue, cnt, m); if (ret) From e9f8a50c3c875480a703e6cc22b341de74f00907 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:35:05 -0300 Subject: [PATCH 064/211] introduce new plugin system for extensions --- include/villas/hooks.h | 13 ------ include/villas/node.h | 6 --- include/villas/plugin.h | 71 ++++++++++++++++++++++++++++ lib/fpga/dft.c | 19 +++++--- lib/fpga/dma.c | 20 +++++--- lib/fpga/fifo.c | 21 +++++---- lib/fpga/intc.c | 19 ++++++-- lib/fpga/model.c | 44 ++++++++++------- lib/fpga/rtds_axis.c | 14 ++++-- lib/fpga/switch.c | 19 +++++--- lib/fpga/timer.c | 14 ++++-- lib/nodes/cbuilder.c | 23 +++++---- lib/nodes/file.c | 26 ++++++----- lib/nodes/fpga.c | 28 ++++++----- lib/nodes/ngsi.c | 28 ++++++----- lib/nodes/opal.c | 28 ++++++----- lib/nodes/socket.c | 32 +++++++------ lib/plugin.c | 83 +++++++++++++++++++++++++++++++++ plugins/hooks/example_hook.c | 15 +++++- plugins/models/simple_circuit.c | 23 +++++---- 20 files changed, 391 insertions(+), 155 deletions(-) create mode 100644 include/villas/plugin.h create mode 100644 lib/plugin.c diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 6f9b76427..e4e6dd68d 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -27,19 +27,6 @@ #include "queue.h" #include "list.h" -#define REGISTER_HOOK(nam, desc, prio, hist, fnc, typ) \ -__attribute__((constructor)) void __register_ ## fnc () { \ - static struct hook h = { \ - .name = nam, \ - .description = desc, \ - .priority = prio, \ - .history = hist, \ - .type = typ, \ - .cb = fnc \ - }; \ - list_push(&hooks, &h); \ -} - /* The configuration of hook parameters is done in "config.h" */ /* Forward declarations */ diff --git a/include/villas/node.h b/include/villas/node.h index d57553402..f237f6866 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -21,12 +21,6 @@ #include "list.h" #include "queue.h" -/* Helper macros for virtual node type */ -#define REGISTER_NODE_TYPE(vt) \ -__attribute__((constructor)) static void __register() { \ - list_push(&node_types, vt); \ -} - extern struct list node_types; /**< Vtable for virtual node sub types */ /* Forward declarations */ diff --git a/include/villas/plugin.h b/include/villas/plugin.h new file mode 100644 index 000000000..8c1c5a681 --- /dev/null +++ b/include/villas/plugin.h @@ -0,0 +1,71 @@ +/** Loadable / plugin support. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include "hooks.h" +#include "api.h" +#include "fpga/ip.h" + +#define REGISTER_PLUGIN(p) \ +__attribute__((constructor)) static void UNIQUE(__ctor)() { \ + list_push(&plugins, p); \ + (p)->load(p); \ +} \ +__attribute__((destructor)) static void UNIQUE(__dtor)() { \ + (p)->unload(p); \ + list_remove(&plugins, p); \ +} + +extern struct list plugins; + +enum plugin_types { + PLUGIN_TYPE_HOOK, + PLUGIN_TYPE_NODE, + PLUGIN_TYPE_API, + PLUGIN_TYPE_FPGA_IP, + PLUGIN_TYPE_MODEL_CBUILDER +}; + +enum plugin_state { + PLUGIN_STATE_DESTROYED, + PLUGIN_STATE_UNLOADED, + PLUGIN_STATE_LOADED +}; + +struct plugin { + char *name; + char *description; + void *handle; + + enum plugin_types type; + enum plugin_state state; + + int (*load)(struct plugin *p); + int (*unload)(struct plugin *p); + + union { + struct api_ressource api; + struct hook hook; + struct node_type node; + }; +}; + +struct plugin * plugin_lookup(char *name, enum plugin_types type); + +int plugin_init(struct plugin *p, char *name, char *path); + +int plugin_load(struct plugin *p); + +int plugin_unload(struct plugin *p); + +int plugin_destroy(struct plugin *p); + +#endif /* _PLUGIN_H_ */ \ No newline at end of file diff --git a/lib/fpga/dft.c b/lib/fpga/dft.c index 8cbfefa85..db5b4be16 100644 --- a/lib/fpga/dft.c +++ b/lib/fpga/dft.c @@ -8,6 +8,8 @@ **********************************************************************************/ #include "log.h" +#include "plugin.h" + #include "fpga/ip.h" #include "fpga/dft.h" @@ -85,11 +87,16 @@ void dft_destroy(struct ip *c) } } -static struct ip_type ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "hls", "hls_dft", NULL }, - .init = dft_init, - .destroy = dft_destroy, - .parse = dft_parse +static struct plugin p = { + .name = "Discrete Fourier Transform", + .description = "Perfom Discrete Fourier Transforms with variable number of harmonics on the FPGA", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "acs.eonerc.rwth-aachen.de", "hls", "hls_dft", NULL }, + .init = dft_init, + .destroy = dft_destroy, + .parse = dft_parse + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/dma.c b/lib/fpga/dma.c index 86c6f3228..ebfdbadc7 100644 --- a/lib/fpga/dma.c +++ b/lib/fpga/dma.c @@ -13,9 +13,10 @@ #include #include -#include - +#include "log.h" +#include "plugin.h" #include "utils.h" + #include "fpga/dma.h" #include "fpga/ip.h" @@ -596,10 +597,15 @@ int dma_reset(struct ip *c) return 0; } -static struct ip_type ip = { - .vlnv = { "xilinx.com", "ip", "axi_dma", NULL }, - .init = dma_init, - .reset = dma_reset +static struct plugin p = { + .name = "Xilinx's AXI4 Direct Memory Access Controller", + .description = "Transfer data streams between VILLASnode and VILLASfpga", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "xilinx.com", "ip", "axi_dma", NULL }, + .init = dma_init, + .reset = dma_reset + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/fifo.c b/lib/fpga/fifo.c index af0df5ead..fab633588 100644 --- a/lib/fpga/fifo.c +++ b/lib/fpga/fifo.c @@ -10,9 +10,9 @@ #include -#include - #include "utils.h" +#include "plugin.h" + #include "fpga/ip.h" #include "fpga/fifo.h" #include "fpga/intc.h" @@ -96,11 +96,16 @@ int fifo_reset(struct ip *c) return 0; } -static struct ip_type ip = { - .vlnv = { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }, - .init = fifo_init, - .parse = fifo_parse, - .reset = fifo_reset +static struct plugin p = { + .name = "Xilinx's AXI4 FIFO data mover", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }, + .init = fifo_init, + .parse = fifo_parse, + .reset = fifo_reset + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/intc.c b/lib/fpga/intc.c index 853e7175c..0e0e32b7d 100644 --- a/lib/fpga/intc.c +++ b/lib/fpga/intc.c @@ -10,9 +10,13 @@ #include "config.h" #include "log.h" +#include "plugin.h" + #include "nodes/fpga.h" + #include "kernel/vfio.h" #include "kernel/kernel.h" + #include "fpga/ip.h" #include "fpga/intc.h" @@ -145,10 +149,15 @@ uint64_t intc_wait(struct ip *c, int irq) } } -static struct ip_type ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL }, - .init = intc_init, - .destroy = intc_destroy +static struct plugin p = { + .name = "Xilinx's programmable interrupt controller", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL }, + .init = intc_init, + .destroy = intc_destroy + } }; -REGISTER_IP_TYPE(&ip) +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/model.c b/lib/fpga/model.c index 737cd6355..6c7f8366f 100644 --- a/lib/fpga/model.c +++ b/lib/fpga/model.c @@ -11,8 +11,9 @@ #include #include -#include -#include +#include "utils.h" +#include "log.h" +#include "plugin.h" #include "fpga/ip.h" #include "fpga/model.h" @@ -353,21 +354,32 @@ int model_param_update(struct model_param *p, struct model_param *u) return 0; } -static struct ip_type ip_hls = { - .vlnv = { NULL, "hls", NULL, NULL }, - .init = model_init, - .destroy = model_destroy, - .dump = model_dump, - .parse = model_parse +static struct plugin p_hls = { + .name = "Xilinx High Level Synthesis (HLS) model", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { NULL, "hls", NULL, NULL }, + .init = model_init, + .destroy = model_destroy, + .dump = model_dump, + .parse = model_parse + } }; -static struct ip_type ip_xsg = { - .vlnv = { NULL, "sysgen", NULL, NULL }, - .init = model_init, - .destroy = model_destroy, - .dump = model_dump, - .parse = model_parse +REGISTER_PLUGIN(&p_hls) + +static struct plugin p_sysgen = { + .name = "Xilinx System Generator for DSP (XSG) model", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { NULL, "sysgen", NULL, NULL }, + .init = model_init, + .destroy = model_destroy, + .dump = model_dump, + .parse = model_parse + } }; -REGISTER_IP_TYPE(&ip_hls) -REGISTER_IP_TYPE(&ip_xsg) \ No newline at end of file +REGISTER_PLUGIN(&p_sysgen) diff --git a/lib/fpga/rtds_axis.c b/lib/fpga/rtds_axis.c index cb35bd2ae..ebb2e1ef6 100644 --- a/lib/fpga/rtds_axis.c +++ b/lib/fpga/rtds_axis.c @@ -10,6 +10,7 @@ #include "log.h" #include "utils.h" +#include "plugin.h" #include "fpga/ip.h" #include "fpga/rtds_axis.h" @@ -49,9 +50,14 @@ double rtds_axis_dt(struct ip *c) return (dt == 0xFFFF) ? -1.0 : (double) dt / RTDS_HZ; } -static struct ip_type ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }, - .dump = rtds_axis_dump +static struct plugin p = { + .name = "RTDS's AXI4-Stream - GTFPGA interface", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }, + .dump = rtds_axis_dump + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/switch.c b/lib/fpga/switch.c index 16a411640..6ba664ccb 100644 --- a/lib/fpga/switch.c +++ b/lib/fpga/switch.c @@ -10,6 +10,8 @@ #include "list.h" #include "log.h" +#include "plugin.h" + #include "fpga/switch.h" #include "fpga/ip.h" @@ -180,11 +182,16 @@ int switch_disconnect(struct ip *c, struct ip *mi, struct ip *si) return 0; } -static struct ip_type ip = { - .vlnv = { "xilinx.com", "ip", "axis_interconnect", NULL }, - .init = switch_init, - .destroy = switch_destroy, - .parse = switch_parse +static struct plugin p = { + .name = "Xilinx's AXI4-Stream switch", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "xilinx.com", "ip", "axis_interconnect", NULL }, + .init = switch_init, + .destroy = switch_destroy, + .parse = switch_parse + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/fpga/timer.c b/lib/fpga/timer.c index a5a9cd4b2..051eeb6b7 100644 --- a/lib/fpga/timer.c +++ b/lib/fpga/timer.c @@ -10,6 +10,7 @@ **********************************************************************************/ #include "config.h" +#include "plugin.h" #include "fpga/ip.h" #include "fpga/timer.h" @@ -31,9 +32,14 @@ int timer_init(struct ip *c) return 0; } -static struct ip_type ip = { - .vlnv = { "xilinx.com", "ip", "axi_timer", NULL }, - .init = timer_init +static struct plugin p = { + .name = "Xilinx's programmable timer / counter", + .description = "", + .type = PLUGIN_TYPE_FPGA_IP, + .ip = { + .vlnv = { "xilinx.com", "ip", "axi_timer", NULL }, + .init = timer_init + } }; -REGISTER_IP_TYPE(&ip) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/cbuilder.c b/lib/nodes/cbuilder.c index e3abebc37..8296b697a 100644 --- a/lib/nodes/cbuilder.c +++ b/lib/nodes/cbuilder.c @@ -8,6 +8,8 @@ #include "node.h" #include "log.h" +#include "plugin.h" + #include "nodes/cbuilder.h" struct list cbmodels; /**< Table of existing CBuilder models */ @@ -114,16 +116,19 @@ int cbuilder_write(struct node *n, struct sample *smps[], unsigned cnt) return 1; } -static struct node_type vt = { +static struct plugin p = { .name = "cbuilder", .description = "RTDS CBuilder model", - .vectorize = 1, - .size = sizeof(struct cbuilder), - .parse = cbuilder_parse, - .open = cbuilder_open, - .close = cbuilder_close, - .read = cbuilder_read, - .write = cbuilder_write, + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 1, + .size = sizeof(struct cbuilder), + .parse = cbuilder_parse, + .open = cbuilder_open, + .close = cbuilder_close, + .read = cbuilder_read, + .write = cbuilder_write, + } }; -REGISTER_NODE_TYPE(&vt) +REGISTER_PLUGIN(&p) diff --git a/lib/nodes/file.c b/lib/nodes/file.c index 8ccd2fbdb..3ca266756 100644 --- a/lib/nodes/file.c +++ b/lib/nodes/file.c @@ -13,6 +13,7 @@ #include "utils.h" #include "timing.h" #include "queue.h" +#include "plugin.h" int file_reverse(struct node *n) { @@ -336,18 +337,21 @@ int file_write(struct node *n, struct sample *smps[], unsigned cnt) return 1; } -static struct node_type vt = { +static struct plugin p = { .name = "file", .description = "support for file log / replay node type", - .vectorize = 1, - .size = sizeof(struct file), - .reverse = file_reverse, - .parse = file_parse, - .print = file_print, - .open = file_open, - .close = file_close, - .read = file_read, - .write = file_write + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 1, + .size = sizeof(struct file), + .reverse = file_reverse, + .parse = file_parse, + .print = file_print, + .open = file_open, + .close = file_close, + .read = file_read, + .write = file_write + } }; -REGISTER_NODE_TYPE(&vt) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/fpga.c b/lib/nodes/fpga.c index d4082317b..a7c65ff1d 100644 --- a/lib/nodes/fpga.c +++ b/lib/nodes/fpga.c @@ -20,6 +20,7 @@ #include "config.h" #include "utils.h" #include "timing.h" +#include "plugin.h" struct fpga fpga; struct pci pci; @@ -431,19 +432,22 @@ int fpga_write(struct node *n, struct sample *smps[], unsigned cnt) return -1; } -static struct node_type vt = { +static struct plugin p = { .name = "fpga", .description = "VILLASfpga PCIe card (libxil)", - .size = sizeof(struct fpga_dm), - .vectorize = 1, - .parse = fpga_parse, - .print = fpga_print, - .open = fpga_open, - .close = fpga_close, - .read = fpga_read, - .write = fpga_write, - .init = fpga_init, - .deinit = fpga_deinit + .type = PLUGIN_TYPE_NODE, + .node = { + .size = sizeof(struct fpga_dm), + .vectorize = 1, + .parse = fpga_parse, + .print = fpga_print, + .open = fpga_open, + .close = fpga_close, + .read = fpga_read, + .write = fpga_write, + .init = fpga_init, + .deinit = fpga_deinit + } }; -REGISTER_NODE_TYPE(&vt) +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index 48f2abb2b..3aebd0368 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -19,6 +19,7 @@ #include "utils.h" #include "timing.h" +#include "plugin.h" /* Some global settings */ static char *name = NULL; @@ -552,19 +553,22 @@ int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt) return ret ? 0 : cnt; } -static struct node_type vt = { +static struct plugin p = { .name = "ngsi", .description = "OMA Next Generation Services Interface 10 (libcurl, libjansson)", - .vectorize = 0, /* unlimited */ - .size = sizeof(struct ngsi), - .parse = ngsi_parse, - .print = ngsi_print, - .open = ngsi_open, - .close = ngsi_close, - .read = ngsi_read, - .write = ngsi_write, - .init = ngsi_init, - .deinit = ngsi_deinit + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 0, /* unlimited */ + .size = sizeof(struct ngsi), + .parse = ngsi_parse, + .print = ngsi_print, + .open = ngsi_open, + .close = ngsi_close, + .read = ngsi_read, + .write = ngsi_write, + .init = ngsi_init, + .deinit = ngsi_deinit + } }; -REGISTER_NODE_TYPE(&vt) +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/opal.c b/lib/nodes/opal.c index 396224743..ad379e5f2 100644 --- a/lib/nodes/opal.c +++ b/lib/nodes/opal.c @@ -13,6 +13,7 @@ #include "opal.h" #include "utils.h" +#incude "plugin.h" /* Private static storage */ static char *async_shmem_name; /**< Shared Memory identifiers and size, provided via argv. */ @@ -277,19 +278,22 @@ int opal_write(struct node *n, struct pool *pool, unsigned cnt) return 1; } -static struct node_type vt = { +static struct plugin p = { .name = "opal", .description = "run as OPAL Asynchronous Process (libOpalAsyncApi)", - .vectoroize = 1, - .size = sizeof(struct opal), - .parse = opal_parse, - .print = opal_print, - .open = opal_open, - .close = opal_close, - .read = opal_read, - .write = opal_write, - .init = opal_init, - .deinit = opal_deinit + .type = PLUGIN_TYPE_NODE, + .node = { + .vectoroize = 1, + .size = sizeof(struct opal), + .parse = opal_parse, + .print = opal_print, + .open = opal_open, + .close = opal_close, + .read = opal_read, + .write = opal_write, + .init = opal_init, + .deinit = opal_deinit + } }; -REGISTER_NODE_TYPE(&vt) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 14771e6f8..48bffbc3e 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -37,6 +37,7 @@ #include "msg.h" #include "sample.h" #include "queue.h" +#include "plugin.h" /* Forward declartions */ static struct node_type vt; @@ -677,21 +678,24 @@ int socket_parse_addr(const char *addr, struct sockaddr *saddr, enum socket_laye return ret; } -static struct node_type vt = { +static struct plugin p = { .name = "socket", .description = "BSD network sockets", - .vectorize = 0, - .size = sizeof(struct socket), - .destroy = socket_destroy, - .reverse = socket_reverse, - .parse = socket_parse, - .print = socket_print, - .open = socket_open, - .close = socket_close, - .read = socket_read, - .write = socket_write, - .init = socket_init, - .deinit = socket_deinit + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 0, + .size = sizeof(struct socket), + .destroy = socket_destroy, + .reverse = socket_reverse, + .parse = socket_parse, + .print = socket_print, + .open = socket_open, + .close = socket_close, + .read = socket_read, + .write = socket_write, + .init = socket_init, + .deinit = socket_deinit + } }; -REGISTER_NODE_TYPE(&vt) +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/plugin.c b/lib/plugin.c new file mode 100644 index 000000000..6b57147b9 --- /dev/null +++ b/lib/plugin.c @@ -0,0 +1,83 @@ +/** Loadable / plugin support. + * + * @author Steffen Vogel + * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include "plugin.h" + +int plugin_init(struct plugin *p, char *name, char *path) +{ + p->name = strdup(name); + p->path = strdup(path); + + p->state = PLUGIN_STATE_UNLOADED; +} + +int plugin_load(struct plugin *p) +{ + p->handle = dlopen(p->path, RTLD_NOW); + if (!p->path) + return -1; + + p->state = PLUGIN_STATE_LOADED; + + return 0; +} + +int plugin_unload(struct plugin *p) +{ + int ret; + + if (p->state != PLUGIN_STATE_LOADED) + return -1; + + ret = dlclose(p->handle); + if (ret) + return -1; + + p->state = UNLOADED; + + return 0; +} + +int plugin_destroy(struct plugin *p) +{ + if (p->state == PLUGIN_STATE_LOADED) + plugin_unload(p); + + free(p->name); + free(p->path); +} + +int plugin_parse(struct plugin *p, config_setting_t *lcs) +{ + const char *path; + + path = config_setting_get_string(cfg); + if (!path) + cerror(cfg, "Setting 'plugin' must be a string."); + + p-> + + handle = dlopen(path, RTLD_NOW); + if (!handle) + error("Failed to load plugin %s", dlerror()); + + list_push_back(&cfg->plugins, handle); + } + + return 0; +} + +struct plugin * plugin_lookup(char *name, enum plugin_types type) +{ + list_foreach(struct plugin *l, &plugins) { + if (l->type == type && strcmp(l->name, name) == 0) + return l + } + + return NULL; +} diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index 843b2734c..f63b0e4c6 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -1,5 +1,6 @@ #include #include +#include static int hook_example(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) { @@ -8,4 +9,16 @@ static int hook_example(struct path *p, struct hook *h, int when, struct sample return 0; } -REGISTER_HOOK("example", "This is just a simple example hook", 99, 0, hook_example, HOOK_PATH_START) \ No newline at end of file +static struct plugin p = { + .name = "example", + .description = "This is just a simple example hook", + .type = LOADABLE_TYPE_HOOK, + .hook = { + .priority = 99, + .history = 0, + .cb = hook_example, + .type = HOOK_PATH_START + } +}; + +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/plugins/models/simple_circuit.c b/plugins/models/simple_circuit.c index 3ab7934b8..2f4786128 100644 --- a/plugins/models/simple_circuit.c +++ b/plugins/models/simple_circuit.c @@ -111,7 +111,8 @@ void simple_circuit_code() { // ----------------------------------------------- #if defined(VILLAS) -#include "nodes/cbuilder.h" +#include +#include double getTimeStep() { @@ -161,15 +162,19 @@ int simple_circuit_write(float inputs[], int len) return 0; } -static struct cbmodel cb = { - .name = "simple_circuit", - .code = simple_circuit_code, - .init = simple_circuit_init, - .read = simple_circuit_read, - .write = simple_circuit_write, - .ram = simple_circuit_ram +static struct plugin p = { + .name = "simple_circuit", + .description = "A simple CBuilder model", + .type = LOADABLE_TYPE_MODEL_CBUILDER, + .cb = { + .code = simple_circuit_code, + .init = simple_circuit_init, + .read = simple_circuit_read, + .write = simple_circuit_write, + .ram = simple_circuit_ram + } }; -REGISTER_CBMODEL(&cb); +REGISTER_PLUGIN(&p) #endif \ No newline at end of file From 88a21ade2ef16d307e896f2f9a07dbf324c4e40a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:36:44 -0300 Subject: [PATCH 065/211] improved read_random() to return read bytes and fix return type --- include/villas/utils.h | 2 +- lib/utils.c | 19 ++++++++----------- src/fpga-tests.c | 10 +++++----- tests/advio.c | 6 ++---- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/include/villas/utils.h b/include/villas/utils.h index 9a144278d..c1e7328a8 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -208,7 +208,7 @@ int version_parse(const char *s, struct version *v); #endif /** Fill buffer with random data */ -int read_random(char *buf, size_t len); +ssize_t read_random(char *buf, size_t len); /** Hexdump bytes */ void printb(void *mem, size_t len); diff --git a/lib/utils.c b/lib/utils.c index 5fba36038..8c4e9329e 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -302,31 +302,28 @@ void * memdup(const void *src, size_t bytes) return dst; } -int read_random(char *buf, size_t len) +ssize_t read_random(char *buf, size_t len) { int fd; - + ssize_t bytes, total; + fd = open("/dev/urandom", O_RDONLY); if (fd < 0) return -1; - - ssize_t bytes, total = 0; - + + bytes = 0; + total = 0; while (total < len) { bytes = read(fd, buf + total, len - total); if (bytes < 0) - goto out; + break; total += bytes; } close(fd); - return 0; -out: - close(fd); - - return -1; + return bytes; } void printb(void *mem, size_t len) diff --git a/src/fpga-tests.c b/src/fpga-tests.c index 0790a2607..0a44b569d 100644 --- a/src/fpga-tests.c +++ b/src/fpga-tests.c @@ -232,8 +232,8 @@ int fpga_test_fifo(struct fpga *f) /* Get some random data to compare */ memset(dst, 0, sizeof(dst)); - ret = read_random((char *) src, sizeof(src)); - if (ret) + len = read_random((char *) src, sizeof(src)); + if (len != sizeof(src)) error("Failed to get random data"); len = fifo_write(fifo, (char *) src, sizeof(src)); @@ -267,7 +267,7 @@ int fpga_test_dma(struct fpga *f) /* Simple DMA can only transfer up to 4 kb due to * PCIe page size burst limitation */ - ssize_t len = dma->dma.inst.HasSg ? 64 << 20 : 1 << 2; + ssize_t len2, len = dma->dma.inst.HasSg ? 64 << 20 : 1 << 2; ret = dma_alloc(dma, &mem, 2 * len, 0); if (ret) @@ -278,8 +278,8 @@ int fpga_test_dma(struct fpga *f) return -1; /* Get new random data */ - ret = read_random(src.base_virt, len); - if (ret) + len2 = read_random(src.base_virt, len); + if (len2 != len) serror("Failed to get random data"); int irq_mm2s = dma->irq; diff --git a/tests/advio.c b/tests/advio.c index 361a33e1f..5622020b4 100644 --- a/tests/advio.c +++ b/tests/advio.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -42,10 +43,7 @@ Test(advio, upload) char buffer[128]; /* Get some random bytes */ - FILE *r = fopen("/dev/urandom", "r"); - cr_assert(r); - - len1 = fread(rnd, 1, sizeof(rnd), r); + len1 = read_random(rnd, sizeof(rnd)); /* Open file for writing */ af = afopen(uri, "w+"); From e7ba883b60e9ea02fd2f48d486432cb7f3ab9453 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:39:55 -0300 Subject: [PATCH 066/211] added flags parameter to afopen() --- include/villas/advio.h | 10 ++++++++-- lib/advio.c | 10 +++++----- tests/advio.c | 6 +++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/villas/advio.h b/include/villas/advio.h index 33435887f..3f8b06e9d 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -9,18 +9,24 @@ #include +enum advio_flags { + ADVIO_MEM = (1 << 0), /**< Instead of a real file, a memory backed stdio stream is used. */ + ADVIO_DIRTY = (1 << 1) /**< The file contents have been modified. We need to upload. */ +}; + struct advio { + int flags; + CURL *curl; FILE *file; const char *url; - bool dirty; /**< The file contents have been modified. We need to upload */ }; typedef struct advio AFILE; -AFILE *afopen(const char *url, const char *mode); +AFILE *afopen(const char *url, const char *mode, int flags); int afclose(AFILE *file); diff --git a/lib/advio.c b/lib/advio.c index 9111db9e1..648524e42 100644 --- a/lib/advio.c +++ b/lib/advio.c @@ -32,7 +32,7 @@ #include "config.h" #include "advio.h" -AFILE *afopen(const char *url, const char *mode) +AFILE *afopen(const char *uri, const char *mode, int flags) { CURLcode res; @@ -80,8 +80,8 @@ AFILE *afopen(const char *url, const char *mode) } af->url = strdup(url); - af->dirty = false; + af->flags = flags & ~ADVIO_DIRTY; return af; out0: curl_easy_cleanup(af->curl); @@ -118,7 +118,7 @@ int afflush(AFILE *af) return ret; /* Only upload file if it was changed */ - if (af->dirty) { + if (af->flags & ADVIO_DIRTY) { CURLcode res; long pos; @@ -137,7 +137,7 @@ int afflush(AFILE *af) if (res != CURLE_OK) return -1; - af->dirty = false; + af->flags &= ADVIO_DIRTY; } return 0; @@ -155,7 +155,7 @@ size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *rest ret = fwrite(ptr, size, nitems, stream->file); if (ret > 0) - stream->dirty = true; + af->flags |= ADVIO_DIRTY; return ret; } diff --git a/tests/advio.c b/tests/advio.c index 5622020b4..3f3900a79 100644 --- a/tests/advio.c +++ b/tests/advio.c @@ -16,7 +16,7 @@ Test(advio, download) const char *url = "http://www.textfiles.com/100/angela.art"; - af = afopen(url, "r"); + af = afopen(url, "r", 0); cr_assert(af, "Failed to download file"); cr_log_info("Opened file %s", url); @@ -46,7 +46,7 @@ Test(advio, upload) len1 = read_random(rnd, sizeof(rnd)); /* Open file for writing */ - af = afopen(uri, "w+"); + af = afopen(uri, "w+", 0); cr_assert(af, "Failed to download file"); len2 = afwrite(rnd, 1, len1, af); @@ -56,7 +56,7 @@ Test(advio, upload) cr_assert_eq(ret, 0, "Failed to close/upload file"); /* Open for reading and comparison */ - af = afopen(uri, "r"); + af = afopen(uri, "r", 0); cr_assert(af, "Failed to download file"); len2 = afread(buffer, 1, len1, af); From 93c620eedff88754491f376805a056b0ee258c35 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:42:14 -0300 Subject: [PATCH 067/211] add support for memory backed local-copy of advio files --- include/villas/advio.h | 3 +++ lib/advio.c | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/villas/advio.h b/include/villas/advio.h index 3f8b06e9d..765c843e8 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -21,6 +21,9 @@ struct advio { FILE *file; const char *url; + /* For use with ADVIO_MODE_MEM */ + char *buf; + size_t size; }; diff --git a/lib/advio.c b/lib/advio.c index 648524e42..f47e9156d 100644 --- a/lib/advio.c +++ b/lib/advio.c @@ -38,7 +38,11 @@ AFILE *afopen(const char *uri, const char *mode, int flags) AFILE *af = alloc(sizeof(AFILE)); - af->file = tmpfile(); + if (flags & ADVIO_MEM) + af->file = open_memstream(&af->buf, &af->size); + else + af->file = tmpfile(); + if (!af->file) goto out2; @@ -113,10 +117,6 @@ int afflush(AFILE *af) { int ret; - ret = fflush(af->file); - if (ret) - return ret; - /* Only upload file if it was changed */ if (af->flags & ADVIO_DIRTY) { CURLcode res; @@ -125,6 +125,12 @@ int afflush(AFILE *af) /* Remember old stream pointer */ pos = ftell(af->file); fseek(af->file, 0, SEEK_SET); + /* Flushing a memory backed stream is sensless */ + if (!(af->flags & ADVIO_MEM)) { + ret = fflush(af->file); + if (ret) + return ret; + } curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(af->curl, CURLOPT_READDATA, af->file); From dea0f1d61c5afa3681029a5712d1d97dd3a5933d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:44:05 -0300 Subject: [PATCH 068/211] advio: code refactoring --- include/villas/advio.h | 2 +- lib/advio.c | 29 +++++++++++------------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/include/villas/advio.h b/include/villas/advio.h index 765c843e8..99897873a 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -20,11 +20,11 @@ struct advio { CURL *curl; FILE *file; - const char *url; /* For use with ADVIO_MODE_MEM */ char *buf; size_t size; + const char *uri; }; typedef struct advio AFILE; diff --git a/lib/advio.c b/lib/advio.c index f47e9156d..fa00b10e5 100644 --- a/lib/advio.c +++ b/lib/advio.c @@ -53,7 +53,7 @@ AFILE *afopen(const char *uri, const char *mode, int flags) curl_easy_setopt(af->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(af->curl, CURLOPT_USERAGENT, USER_AGENT); - curl_easy_setopt(af->curl, CURLOPT_URL, url); + curl_easy_setopt(af->curl, CURLOPT_URL, uri); curl_easy_setopt(af->curl, CURLOPT_WRITEDATA, af->file); res = curl_easy_perform(af->curl); @@ -83,15 +83,12 @@ AFILE *afopen(const char *uri, const char *mode, int flags) goto out0; /* no please fail here */ } - af->url = strdup(url); - + af->uri = strdup(uri); af->flags = flags & ~ADVIO_DIRTY; + return af; out0: curl_easy_cleanup(af->curl); - - printf("Failed to download file (%d): %s\n", res, curl_easy_strerror(res)); - out1: fclose(af->file); out2: free(af); @@ -103,11 +100,8 @@ int afclose(AFILE *af) int ret; ret = afflush(af); - curl_easy_cleanup(af->curl); - fclose(af->file); - free(af); return ret; @@ -122,9 +116,6 @@ int afflush(AFILE *af) CURLcode res; long pos; - /* Remember old stream pointer */ - pos = ftell(af->file); - fseek(af->file, 0, SEEK_SET); /* Flushing a memory backed stream is sensless */ if (!(af->flags & ADVIO_MEM)) { ret = fflush(af->file); @@ -135,10 +126,12 @@ int afflush(AFILE *af) curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(af->curl, CURLOPT_READDATA, af->file); + pos = ftell(af->file); /* Remember old stream pointer */ + fseek(af->file, 0, SEEK_SET); + res = curl_easy_perform(af->curl); - /* Restore old stream pointer */ - fseek(af->file, pos, SEEK_SET); + fseek(af->file, pos, SEEK_SET); /* Restore old stream pointer */ if (res != CURLE_OK) return -1; @@ -149,16 +142,16 @@ int afflush(AFILE *af) return 0; } -size_t afread(void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream) +size_t afread(void *restrict ptr, size_t size, size_t nitems, AFILE *restrict af) { - return fread(ptr, size, nitems, stream->file); + return fread(ptr, size, nitems, af->file); } -size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream) +size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict af) { size_t ret; - ret = fwrite(ptr, size, nitems, stream->file); + ret = fwrite(ptr, size, nitems, af->file); if (ret > 0) af->flags |= ADVIO_DIRTY; From ac7a87b8fc2fce138702a20ad0d4fa955fa3e16c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Feb 2017 14:44:29 -0300 Subject: [PATCH 069/211] cbuilder: coding style --- plugins/models/simple_circuit.c | 171 +++++++++++++++----------------- 1 file changed, 82 insertions(+), 89 deletions(-) diff --git a/plugins/models/simple_circuit.c b/plugins/models/simple_circuit.c index 2f4786128..4e3b66567 100644 --- a/plugins/models/simple_circuit.c +++ b/plugins/models/simple_circuit.c @@ -1,114 +1,113 @@ -// This is c-code for CBuilder component for Subsystem 2 -// Solver used as in RTDS: Resistive companion (Dommel's algo) -// Subsystem 1 is modelled in RSCAD -// -//% Circuit topology -// % -//% *** Subsystem 1 (SS1) *** % *** Subsystem 2 (SS2) *** -//% % -//% |---------| |---------| % -//% |---------| R1 |-------| L1 |----%-------|---------| -//% | |---------| |---------| % | | -//% | % | | -//% ----- % ----- ----- -//% | + | % | | | | -//% | E | % |C2 | | R2| -//% | - | % | | | | -//% ----- % ----- ----- -//% | % | | -//% |------------------------------------------%------------------ -// % -// % +/** This is c-code for CBuilder component for Subsystem 2 + * Solver used as in RTDS: Resistive companion (Dommel's algo) + * Subsystem 1 is modelled in RSCAD + * + * % Circuit topology + * % + * % *** Subsystem 1 (SS1) *** % *** Subsystem 2 (SS2) *** + * % % + * % |---------| |---------| % + * % |---------| R1 |-------| L1 |----%-------|---------| + * % | |---------| |---------| % | | + * % | % | | + * % ----- % ----- ----- + * % | + | % | | | | + * % | E | % |C2 | | R2| + * % | - | % | | | | + * % ----- % ----- ----- + * % | % | | + * % |------------------------------------------%------------------ + * % + * % + */ -// ----------------------------------------------- -// Variables declared here may be used as parameters -// inputs or outputs -// The have to match with whats in Subsystem.h -// ----------------------------------------------- + +/* Variables declared here may be used as parameters inputs or outputs + * The have to match with whats in Subsystem.h */ #if defined(VILLAS) || SECTION == INPUTS double IntfIn; -#endif +#endif /* defined(VILLAS) || SECTION == INPUTS */ #if defined(VILLAS) || SECTION == OUTPUTS double IntfOut; -#endif +#endif /* defined(VILLAS) || SECTION == OUTPUTS */ #if defined(VILLAS) || SECTION == PARAMS -double R2; // Resistor [Ohm] in SS2 -double C2; // Capacitance [F] in SS2 -#endif +double R2; /**< Resistor [Ohm] in SS2 */ +double C2; /**< Capacitance [F] in SS2 */ +#endif /* defined(VILLAS) || SECTION == PARAMS */ -// ----------------------------------------------- -// Variables declared here may be used in both the -// RAM: and CODE: sections below. -// ----------------------------------------------- +/* Variables declared here may be used in both the RAM: and CODE: sections below. */ #if defined(VILLAS) || SECTION == STATIC -double dt; -double GR2, GC2; //Inductances of components -double GnInv; //Inversion of conductance matrix (here only scalar) -double vC2Hist, iC2Hist, AC2; // history meas. and current of dynamic elements -double Jn; //source vector in equation Gn*e=Jn -double eSS2; //node voltage solution -#endif +double dt; +double GR2, GC2; /**< Inductances of components */ +double GnInv; /**< Inversion of conductance matrix (here only scalar) */ +double vC2Hist, iC2Hist, AC2; /**< History meas. and current of dynamic elements */ +double Jn; /**< Source vector in equation Gn*e=Jn */ +double eSS2; /**< Node voltage solution */ +#endif /* defined(VILLAS) || SECTION == STATIC */ -// ----------------------------------------------- -// This section should contain any 'c' functions -// to be called from the RAM section (either -// RAM_PASS1 or RAM_PASS2). Example: -// -// static double myFunction(double v1, double v2) -// { -// return(v1*v2); -// } -// ----------------------------------------------- + +/* This section should contain any 'c' functions + * to be called from the RAM section (either + * RAM_PASS1 or RAM_PASS2). Example: + * + * static double myFunction(double v1, double v2) + * { + * return(v1*v2); + * } + */ #if defined(VILLAS) || SECTION == RAM_FUNCTIONS -/* Nothing here */ -#endif -// ----------------------------------------------- -// Place C code here which computes constants -// required for the CODE: section below. The C -// code here is executed once, prior to the start -// of the simulation case. -// ----------------------------------------------- +/* Nothing here */ + +#endif /* defined(VILLAS) || SECTION == RAM_FUNCTIONS */ + + +/* Place C code here which computes constants + * required for the CODE: section below. The C + * code here is executed once, prior to the start + * of the simulation case. + */ #if defined(VILLAS) || SECTION == RAM void simple_circuit_ram() { - GR2 = 1/R2; - GC2 = 2*C2/dt; //trapezoidal rule - GnInv = 1/(GR2+GC2); //eq. conductance (inverted) - - vC2Hist = 0.0; //Voltage over C2 in previous time step - iC2Hist = 0.0; //Current through C2 in previous time step + GR2 = 1/R2; + GC2 = 2*C2/dt; /**< Trapezoidal rule */ + GnInv = 1/(GR2+GC2); /**< eq. conductance (inverted) */ + + vC2Hist = 0.0; /**< Voltage over C2 in previous time step */ + iC2Hist = 0.0; /**< Current through C2 in previous time step */ } -#endif +#endif /* defined(VILLAS) || SECTION == RAM */ -// ----------------------------------------------- -// Place C code here which runs on the RTDS. The -// code below is entered once each simulation -// step. + +// ----------------------------------------------- +// Place C code here which runs on the RTDS. The +// code below is entered once each simulation +// step. // ----------------------------------------------- #if defined(VILLAS) || SECTION == CODE void simple_circuit_code() { - //Update source vector + /* Update source vector */ AC2 = iC2Hist+vC2Hist*GC2; Jn = IntfIn+AC2; - //Solution of the equation Gn*e=Jn; - eSS2 = GnInv*Jn; - //Post step -> calculate the voltage and current for C2 for next step and set interface output + + /* Solution of the equation Gn*e=Jn; */ + eSS2 = GnInv*Jn; + + /* Post step -> calculate the voltage and current for C2 for next step and set interface output */ vC2Hist= eSS2; iC2Hist = vC2Hist*GC2-AC2; IntfOut = eSS2; } -#endif +#endif /* defined(VILLAS) || SECTION == CODE */ -// ----------------------------------------------- -// Interface to VILLASnode -// ----------------------------------------------- +/* Interface to VILLASnode */ #if defined(VILLAS) #include @@ -119,9 +118,7 @@ double getTimeStep() return dt; } -// ----------------------------------------------- -// Place C code here which intializes parameters -// ----------------------------------------------- +/** Place C code here which intializes parameters */ int simple_circuit_init(struct cbuilder *cb) { if (cb->paramlen < 2) @@ -136,9 +133,7 @@ int simple_circuit_init(struct cbuilder *cb) return 0; /* success */ } -// ----------------------------------------------- -// Place C code here reads model outputs -// ----------------------------------------------- +/** Place C code here reads model outputs */ int simple_circuit_read(float outputs[], int len) { if (len < 1) @@ -149,9 +144,7 @@ int simple_circuit_read(float outputs[], int len) return 1; /* 1 value per sample */ } -// ----------------------------------------------- -// Place C code here which updates model inputs -// ----------------------------------------------- +/** Place C code here which updates model inputs */ int simple_circuit_write(float inputs[], int len) { if (len < 1) @@ -177,4 +170,4 @@ static struct plugin p = { REGISTER_PLUGIN(&p) -#endif \ No newline at end of file +#endif /* defined(VILLAS) */ \ No newline at end of file From 5beb70d0c60849cb0d89ea10060f939659370a28 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 15 Feb 2017 17:54:52 -0300 Subject: [PATCH 070/211] Updated and modularised Makefiles --- lib/Makefile.inc | 16 ++++------------ lib/fpga/Makefile.inc | 6 ++++++ lib/hooks/Makefile.inc | 1 + lib/nodes/Makefile.inc | 1 + 4 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 lib/fpga/Makefile.inc create mode 100644 lib/hooks/Makefile.inc create mode 100644 lib/nodes/Makefile.inc diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 787c62dba..728653992 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -8,12 +8,15 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ queue.c memory.c advio.c \ ) \ - $(wildcard lib/hooks/*.c) \ LIB_CFLAGS = $(CFLAGS) -fPIC LIB_LDFLAGS = -shared LIB_LDLIBS = $(LDLIBS) -ldl -lrt +-include lib/hooks/Makefile.inc +-include lib/apis/Makefile.inc +-include lib/fpga/Makefile.inc + ######## Node types ######## # Enable Socket node type when libnl3 is available @@ -23,8 +26,6 @@ ifeq ($(shell pkg-config libnl-route-3.0; echo $$?),0) LIB_SRCS += $(addprefix lib/kernel/, nl.c tc.c if.c) LIB_SRCS += $(addprefix lib/, msg.c) LIB_PKGS += libnl-route-3.0 -else - $(error Missing dependecy: libnl-3) endif endif @@ -33,10 +34,7 @@ ifndef WITHOUT_FPGA ifeq ($(shell pkg-config libxil; echo $$?),0) LIB_SRCS += $(addprefix lib/nodes/, fpga.c) LIB_SRCS += $(addprefix lib/kernel/, pci.c vfio.c) - LIB_SRCS += $(wildcard lib/fpga/*.c) PKGS += libxil -else - $(error Missing dependecy: libxil) endif endif @@ -45,8 +43,6 @@ ifndef WITHOUT_NGSI ifeq ($(shell pkg-config libcurl jansson; echo $$?),0) LIB_SRCS += lib/nodes/ngsi.c LIB_PKGS += libcurl jansson -else - $(error Missing dependecies: libjansson) endif endif @@ -55,8 +51,6 @@ ifndef WITHOUT_WEBSOCKETS ifeq ($(shell pkg-config libwebsockets jansson; echo $$?),0) LIB_SRCS += lib/nodes/websocket.c LIB_PKGS += libwebsockets jansson -else - $(error Missing dependecies: libwebsockets or libjansson) endif endif @@ -73,8 +67,6 @@ ifneq (,$(wildcard thirdparty/opal/include/AsyncApi.h)) CFLAGS += -m32 LDFLAGS += -m32 BUILDDIR := $(BUILDDIR)32 -else - $(error Missing dependecy: libOpalUtils libOpalAsyncApiCore) endif endif diff --git a/lib/fpga/Makefile.inc b/lib/fpga/Makefile.inc new file mode 100644 index 000000000..3881fd813 --- /dev/null +++ b/lib/fpga/Makefile.inc @@ -0,0 +1,6 @@ +# Enable VILLASfpga support when libxil is available +ifndef WITHOUT_FPGA +ifeq ($(shell pkg-config libxil; echo $$?),0) + LIB_SRCS += $(wildcard lib/fpga/*.c) +endif +endif \ No newline at end of file diff --git a/lib/hooks/Makefile.inc b/lib/hooks/Makefile.inc new file mode 100644 index 000000000..488c96ade --- /dev/null +++ b/lib/hooks/Makefile.inc @@ -0,0 +1 @@ +LIB_SRCS += $(wildcard lib/hooks/*.c) \ No newline at end of file diff --git a/lib/nodes/Makefile.inc b/lib/nodes/Makefile.inc new file mode 100644 index 000000000..20d41c0fb --- /dev/null +++ b/lib/nodes/Makefile.inc @@ -0,0 +1 @@ +LIB_SRC += $(wildcard lib/nodes/*.c) \ No newline at end of file From 3ebfaf287c0e241f9abe8872cf3113e74d889b12 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 15 Feb 2017 17:57:03 -0300 Subject: [PATCH 071/211] remove obsolete preprocessor macros --- include/villas/fpga/ip.h | 6 ------ include/villas/nodes/cbuilder.h | 5 ----- 2 files changed, 11 deletions(-) diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index c3d2570aa..cfe64fdb5 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -20,12 +20,6 @@ #include "fpga/intc.h" #include "nodes/fpga.h" -#define REGISTER_IP_TYPE(ip) \ -__attribute__((constructor)) static \ -void UNIQUE(__register_)() { \ - list_push(&ip_types, ip); \ -} - extern struct list ip_types; /**< Table of existing FPGA IP core drivers */ enum ip_state { diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index 57b36a268..f67589589 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -19,11 +19,6 @@ #include "list.h" -/* Helper macros for registering new models */ -#define REGISTER_CBMODEL(cb) \ -__attribute__((constructor)) static void __register() { \ - list_push(&cbmodels, cb); \ -} extern struct list cbmodels; /**< Table of existing CBuilder models */ From 90cad8e8290f3e347f61d848342059609ea032db Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 15 Feb 2017 17:57:45 -0300 Subject: [PATCH 072/211] refactored FPGA VLNV parser / comparison code --- include/villas/fpga/ip.h | 7 ++++-- lib/fpga/ip.c | 52 ++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index cfe64fdb5..72a7cda7d 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -77,10 +77,13 @@ struct ip { struct ip * ip_vlnv_lookup(struct list *l, const char *vendor, const char *library, const char *name, const char *version); /** Check if IP block \p c matched VLNV. */ -int ip_vlnv_match(struct ip *c, const char *vendor, const char *library, const char *name, const char *version); +int ip_vlnv_cmp(struct ip_vlnv *a, struct ip_vlnv *b); /** Tokenizes VLNV \p vlnv and stores it into \p c */ -int ip_vlnv_parse(struct ip *c, const char *vlnv); +int ip_vlnv_parse(struct ip_vlnv *c, const char *vlnv); + +/** Release memory allocated by ip_vlnv_parse(). */ +void ip_vlnv_destroy(struct ip_vlnv *v); int ip_init(struct ip *c); diff --git a/lib/fpga/ip.c b/lib/fpga/ip.c index d97c49cf2..4bb87f07c 100644 --- a/lib/fpga/ip.c +++ b/lib/fpga/ip.c @@ -12,40 +12,36 @@ #include "config.h" -struct list ip_types; /**< Table of existing FPGA IP core drivers */ - -struct ip * ip_vlnv_lookup(struct list *l, const char *vendor, const char *library, const char *name, const char *version) +int ip_vlnv_cmp(struct ip_vlnv *a, struct ip_vlnv *b) { - list_foreach(struct ip *c, l) { - if (ip_vlnv_match(c, vendor, library, name, version)) - return c; - } - - return NULL; + return ((!a->vendor || !b->vendor || !strcmp(a->vendor, b->vendor )) && + (!a->library || !b->library || !strcmp(a->library, b->library)) && + (!a->name || !b->name || !strcmp(a->name, b->name )) && + (!a->version || !b->version || !strcmp(a->version, b->version))) ? 0 : 1; } -int ip_vlnv_match(struct ip *c, const char *vendor, const char *library, const char *name, const char *version) -{ - return ((vendor && strcmp(c->vlnv.vendor, vendor)) || - (library && strcmp(c->vlnv.library, library)) || - (name && strcmp(c->vlnv.name, name)) || - (version && strcmp(c->vlnv.version, version))) ? 0 : 1; -} - -int ip_vlnv_parse(struct ip *c, const char *vlnv) +int ip_vlnv_parse(struct ip_vlnv *c, const char *vlnv) { char *tmp = strdup(vlnv); - c->vlnv.vendor = strdup(strtok(tmp, ":")); - c->vlnv.library = strdup(strtok(NULL, ":")); - c->vlnv.name = strdup(strtok(NULL, ":")); - c->vlnv.version = strdup(strtok(NULL, ":")); + c->vendor = strdup(strtok(tmp, ":")); + c->library = strdup(strtok(NULL, ":")); + c->name = strdup(strtok(NULL, ":")); + c->version = strdup(strtok(NULL, ":")); free(tmp); return 0; } +void ip_vlnv_destroy(struct ip_vlnv *v) +{ + free(c->vendor); + free(c->library); + free(c->name); + free(c->version); +} + int ip_init(struct ip *c) { int ret; @@ -74,10 +70,7 @@ void ip_destroy(struct ip *c) if (c->_vt && c->_vt->destroy) c->_vt->destroy(c); - free(c->vlnv.vendor); - free(c->vlnv.library); - free(c->vlnv.name); - free(c->vlnv.version); + ip_vlnv_destroy(c->vlnv); } void ip_dump(struct ip *c) @@ -105,13 +98,14 @@ int ip_parse(struct ip *c, config_setting_t *cfg) if (!config_setting_lookup_string(cfg, "vlnv", &vlnv)) cerror(cfg, "IP %s is missing the VLNV identifier", c->name); - ret = ip_vlnv_parse(c, vlnv); + ret = ip_vlnv_parse(&c->vlnv, vlnv); if (ret) cerror(cfg, "Failed to parse VLNV identifier"); /* Try to find matching IP type */ - list_foreach(struct ip_type *t, &ip_types) { - if (ip_vlnv_match(c, t->vlnv.vendor, t->vlnv.library, t->vlnv.name, t->vlnv.version)) { + list_foreach(struct plugin *l, &plugins) { + if (l->type == PLUGIN_TYPE_FPGA_IP && + !ip_vlnv_match(&c->ip.vlnv, &l->ip.vlnv)) { c->_vt = t; break; } From 098dd6f6124b266f4c869ab0f5cab4f3befbb022 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 15 Feb 2017 17:58:15 -0300 Subject: [PATCH 073/211] refactored cbmodel -> cbuilder_model --- include/villas/nodes/cbuilder.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index f67589589..c2364e018 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -19,14 +19,25 @@ #include "list.h" +/* Forward declaration */ +struct cbuilder; -extern struct list cbmodels; /**< Table of existing CBuilder models */ +struct cbuilder_model { + char *name; + + void (*code)(); + void (*ram)(); + + int (*init)(struct cbuilder *cb); + int (*read)(float inputs[], int len); + int (*write)(float outputs[], int len); +}; struct cbuilder { unsigned long step, read; double timestep; - struct cbmodel *model; + struct cbuilder_model *model; float *params; int paramlen; @@ -41,15 +52,4 @@ struct cbuilder { pthread_cond_t cv; }; -struct cbmodel { - char *name; - - void (*code)(); - void (*ram)(); - - int (*init)(struct cbuilder *cb); - int (*read)(float inputs[], int len); - int (*write)(float outputs[], int len); -}; - #endif /** _NODES_CBUILDER_H_ @} */ \ No newline at end of file From 7cab0538aba8898fb6b7e7c9114896f8dee5855f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:04:12 -0300 Subject: [PATCH 074/211] use #pragma once instead of #ifdef --- config.h | 5 +--- include/villas/advio.h | 7 ++---- include/villas/cfg.h | 7 ++---- include/villas/hist.h | 7 ++---- include/villas/kernel/if.h | 7 ++---- include/villas/kernel/kernel.h | 7 ++---- include/villas/kernel/nl.h | 7 ++---- include/villas/kernel/pci.h | 7 ++---- include/villas/kernel/rt.h | 4 +-- include/villas/kernel/tc.h | 7 ++---- include/villas/kernel/vfio.h | 7 ++---- include/villas/list.h | 7 ++---- include/villas/log.h | 8 ++---- include/villas/memory.h | 7 ++---- include/villas/msg.h | 7 ++---- include/villas/msg_format.h | 7 ++---- include/villas/node.h | 5 ++-- include/villas/nodes/cbuilder.h | 5 ++-- include/villas/nodes/file.h | 5 ++-- include/villas/nodes/fpga.h | 42 +++++++------------------------- include/villas/nodes/ngsi.h | 5 ++-- include/villas/nodes/opal.h | 5 ++-- include/villas/nodes/socket.h | 5 ++-- include/villas/nodes/websocket.h | 8 +++--- include/villas/path.h | 5 ++-- include/villas/plugin.h | 5 +--- include/villas/pool.h | 7 ++---- include/villas/queue.h | 7 +----- include/villas/sample.h | 7 ++---- include/villas/timing.h | 7 ++---- include/villas/utils.h | 7 ++---- 31 files changed, 67 insertions(+), 166 deletions(-) diff --git a/config.h b/config.h index b425ce9c2..3f9b62cca 100644 --- a/config.h +++ b/config.h @@ -10,8 +10,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ +#pragma once #ifndef _GIT_REV #define _GIT_REV "nogit" @@ -70,5 +69,3 @@ struct settings { int debug; /**< Debug log level */ double stats; /**< Interval for path statistics. Set to 0 to disable themo disable them. */ }; - -#endif /* _CONFIG_H_ */ diff --git a/include/villas/advio.h b/include/villas/advio.h index 99897873a..b4ab47bcc 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -2,8 +2,7 @@ * */ -#ifndef _ADVIO_H_ -#define _ADVIO_H_ +#pragma once #include @@ -40,6 +39,4 @@ int afflush(AFILE *file); #define afeof(af) feof(af->file) size_t afread(void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream); -size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream); - -#endif /* _ADVIO_H_ */ \ No newline at end of file +size_t afwrite(const void *restrict ptr, size_t size, size_t nitems, AFILE *restrict stream); \ No newline at end of file diff --git a/include/villas/cfg.h b/include/villas/cfg.h index 9d8dcea75..2065d6d95 100644 --- a/include/villas/cfg.h +++ b/include/villas/cfg.h @@ -11,8 +11,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _CFG_H_ -#define _CFG_H_ +#pragma once #include @@ -106,6 +105,4 @@ int cfg_parse_hook(config_setting_t *cfg, struct list *list); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *set); - -#endif /* _CFG_H_ */ +int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct cfg *set); \ No newline at end of file diff --git a/include/villas/hist.h b/include/villas/hist.h index 72b232a21..fefd3a728 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _HIST_H_ -#define _HIST_H_ +#pragma once #include @@ -75,6 +74,4 @@ void hist_plot(struct hist *h); char * hist_dump(struct hist *h); /** Prints Matlab struct containing all infos to file. */ -void hist_matlab(struct hist *h, FILE *f); - -#endif /* _HIST_H_ */ +void hist_matlab(struct hist *h, FILE *f); \ No newline at end of file diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h index 6099b0280..8317270d7 100644 --- a/include/villas/kernel/if.h +++ b/include/villas/kernel/if.h @@ -10,8 +10,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_IF_H_ -#define _KERNEL_IF_H_ +#pragma once #include #include @@ -104,6 +103,4 @@ int if_get_irqs(struct interface *i); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int if_set_affinity(struct interface *i, int affinity); - -#endif /* _KERNEL_IF_H_ */ +int if_set_affinity(struct interface *i, int affinity); \ No newline at end of file diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index 86d99406d..b8bf1351d 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_KERNEL_H_ -#define _KERNEL_KERNEL_H_ +#pragma once #include @@ -67,6 +66,4 @@ int kernel_module_set_param(const char *module, const char *param, const char *v int kernel_get_cacheline_size(); /** Set SMP affinity of IRQ */ -int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); - -#endif /* _KERNEL_KERNEL_H_ */ +int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); \ No newline at end of file diff --git a/include/villas/kernel/nl.h b/include/villas/kernel/nl.h index 1e7593626..4a3e32f4a 100644 --- a/include/villas/kernel/nl.h +++ b/include/villas/kernel/nl.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_NL_H_ -#define _KERNEL_NL_H_ +#pragma once #include #include @@ -25,6 +24,4 @@ int nl_get_egress(struct nl_addr *addr); struct nl_sock * nl_init(); /** Close and free global netlink socket. */ -void nl_shutdown(); - -#endif /* _KERNEL_NL_H_ */ \ No newline at end of file +void nl_shutdown(); \ No newline at end of file diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h index acb0bab39..ae4e6417a 100644 --- a/include/villas/kernel/pci.h +++ b/include/villas/kernel/pci.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. **********************************************************************************/ -#ifndef _KERNEL_PCI_H_ -#define _KERNEL_PCI_H_ +#pragma once #include "list.h" @@ -62,6 +61,4 @@ struct pci_dev * pci_lookup_device(struct pci *p, struct pci_dev *filter); int pci_attach_driver(struct pci_dev *d, const char *driver); /** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */ -int pci_get_iommu_group(struct pci_dev *d); - -#endif /* _KERNEL_PCI_H_ */ \ No newline at end of file +int pci_get_iommu_group(struct pci_dev *d); \ No newline at end of file diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index dc6d0ae77..c4b5cd2bf 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -7,9 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_RT_H_ -#define _KERNEL_RT_H_ +#pragma once int rt_init(int affinity, int priority); -#endif /* _KERNEL_RT_H_ */ \ No newline at end of file diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h index 147e7dc80..48fdc67af 100644 --- a/include/villas/kernel/tc.h +++ b/include/villas/kernel/tc.h @@ -12,8 +12,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_TC_H_ -#define _KERNEL_TC_H_ +#pragma once #include @@ -82,6 +81,4 @@ int tc_netem(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hd * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark); - -#endif /* _TC_H_ */ +int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark); \ No newline at end of file diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 928f518cb..b03a5c4a4 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _KERNEL_VFIO_H_ -#define _KERNEL_VFIO_H_ +#pragma once #include #include @@ -108,6 +107,4 @@ int vfio_map_dma(struct vfio_container *c, struct dma_mem *mem); int vfio_unmap_dma(struct vfio_container *c, struct dma_mem *mem); /** munmap() a region which has been mapped by vfio_map_region() */ -int vfio_unmap_region(struct vfio_dev *d, int idx); - -#endif /* _KERNEL_VFIO_H_ */ +int vfio_unmap_region(struct vfio_dev *d, int idx); \ No newline at end of file diff --git a/include/villas/list.h b/include/villas/list.h index 4487ad10c..2e3e5ec6c 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -13,8 +13,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _LIST_H_ -#define _LIST_H_ +#pragma once #include #include @@ -97,6 +96,4 @@ int list_count(struct list *l, cmp_cb_t cmp, void *ctx); int list_contains(struct list *l, void *p); /** Sort the list using the quicksort algorithm of libc */ -void list_sort(struct list *l, cmp_cb_t cmp); - -#endif /* _LIST_H_ */ +void list_sort(struct list *l, cmp_cb_t cmp); \ No newline at end of file diff --git a/include/villas/log.h b/include/villas/log.h index dbd7bda46..1fa7ead85 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _LOG_H_ -#define _LOG_H_ +#pragma once #include #include @@ -121,7 +120,4 @@ void serror(const char *fmt, ...) /** Print configuration error and exit. */ void cerror(config_setting_t *cfg, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); - -#endif /* _LOG_H_ */ - + __attribute__ ((format(printf, 2, 3))); \ No newline at end of file diff --git a/include/villas/memory.h b/include/villas/memory.h index f6e3064f5..4890b490a 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -10,8 +10,7 @@ #include #include -#ifndef _MEMORY_H_ -#define _MEMORY_H_ +#pragma once #define HUGEPAGESIZE (1 << 21) @@ -56,6 +55,4 @@ void * memory_alloc_aligned(const struct memtype *m, size_t len, size_t alignmen int memory_free(const struct memtype *m, void *ptr, size_t len); extern const struct memtype memtype_heap; -extern const struct memtype memtype_hugepage; - -#endif /* _MEMORY_H_ */ \ No newline at end of file +extern const struct memtype memtype_hugepage; \ No newline at end of file diff --git a/include/villas/msg.h b/include/villas/msg.h index 2fb032f8c..7916e8c28 100644 --- a/include/villas/msg.h +++ b/include/villas/msg.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _MSG_H_ -#define _MSG_H_ +#pragma once #include @@ -37,6 +36,4 @@ void msg_hdr_swap(struct msg *m); * @retval 0 The message header is valid. * @retval <0 The message header is invalid. */ -int msg_verify(struct msg *m); - -#endif /* _MSG_H_ */ +int msg_verify(struct msg *m); \ No newline at end of file diff --git a/include/villas/msg_format.h b/include/villas/msg_format.h index 5e9e2bccc..5d1be6e8d 100644 --- a/include/villas/msg_format.h +++ b/include/villas/msg_format.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _MSG_FORMAT_H_ -#define _MSG_FORMAT_H_ +#pragma once #include @@ -95,6 +94,4 @@ struct msg float f; /**< Floating point values (note msg::endian) */ uint32_t i; /**< Integer values (note msg::endian) */ } data[]; -} __attribute__((packed)); - -#endif /* _MSG_FORMAT_H_ */ +} __attribute__((packed)); \ No newline at end of file diff --git a/include/villas/node.h b/include/villas/node.h index f237f6866..af24a35cb 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -10,8 +10,7 @@ * @{ *********************************************************************************/ -#ifndef _NODE_H_ -#define _NODE_H_ +#pragma once #include #include @@ -250,4 +249,4 @@ int node_read(struct node *n, struct sample *smps[], unsigned cnt); int node_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NODE_H_ @} */ +/** @} */ diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index c2364e018..817b52362 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -12,8 +12,7 @@ * @{ *********************************************************************************/ -#ifndef _NODES_CBUILDER_H_ -#define _NODES_CBUILDER_H_ +#pragma once #include @@ -52,4 +51,4 @@ struct cbuilder { pthread_cond_t cv; }; -#endif /** _NODES_CBUILDER_H_ @} */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/nodes/file.h b/include/villas/nodes/file.h index 70e0e5e7b..64febba1b 100644 --- a/include/villas/nodes/file.h +++ b/include/villas/nodes/file.h @@ -15,8 +15,7 @@ *********************************************************************************/ -#ifndef _NODES_FILE_H_ -#define _NODES_FILE_H_ +#pragma once #include "node.h" @@ -73,4 +72,4 @@ int file_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int file_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NODES_FILE_H_ @} */ +/** @} */ diff --git a/include/villas/nodes/fpga.h b/include/villas/nodes/fpga.h index 752d0b57c..5685f654d 100644 --- a/include/villas/nodes/fpga.h +++ b/include/villas/nodes/fpga.h @@ -14,44 +14,22 @@ * @{ *********************************************************************************/ -#ifndef _NODES_FPGA_H_ -#define _NODES_FPGA_H_ +#pragma once #include "kernel/vfio.h" #include "kernel/pci.h" -#include "fpga/dma.h" -#include "fpga/ip.h" -#include "fpga/intc.h" +#include "fpga/ips/dma.h" #include "node.h" #include "list.h" +/* Forward declarations */ +struct fpga_ip; + +/** The node type */ struct fpga { - struct pci_dev filter; /**< Filter for PCI device. */ - struct vfio_dev vd; /**< VFIO device handle. */ - - int do_reset; /**< Reset VILLASfpga during startup? */ - int affinity; /**< Affinity for MSI interrupts */ - - struct list ips; /**< List of IP components on FPGA. */ - - char *map; /**< PCI BAR0 mapping for register access */ - - size_t maplen; - size_t dmalen; - - /* Some IP cores are special and referenced here */ - struct ip *intc; - struct ip *reset; - struct ip *sw; - - config_setting_t *cfg; -}; - -struct fpga_dm { - struct ip *ip; - const char *ip_name; + struct fpga_ip *ip; int use_irqs; @@ -61,8 +39,6 @@ struct fpga_dm { FPGA_DM_DMA, FPGA_DM_FIFO } type; - - struct fpga *card; }; /** @see node_vtable::init */ @@ -75,7 +51,7 @@ int fpga_deinit(); int fpga_parse(struct node *n, config_setting_t *cfg); /** Parse the 'fpga' section in the configuration file */ -int fpga_parse_card(struct fpga *v, int argc, char * argv[], config_setting_t *cfg); +int fpga_parse_cards(config_setting_t *cfg); /** @see node_vtable::print */ char * fpga_print(struct node *n); @@ -101,4 +77,4 @@ int fpga_reset(struct fpga *f); /** Dump some details about the fpga card */ void fpga_dump(struct fpga *f); -#endif /** _NODES_FPGA_H_ @} */ +/** @} */ diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index f40b5a257..9a184e690 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -18,8 +18,7 @@ * @{ **********************************************************************************/ -#ifndef _NODES_NGSI_H_ -#define _NODES_NGSI_H_ +#pragma once #include #include @@ -81,4 +80,4 @@ int ngsi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NODES_NGSI_H_ @} */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index dd3a5b704..5f2db6aea 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -14,8 +14,7 @@ * @{ **********************************************************************************/ -#ifndef _NODES_OPAL_H_ -#define _NODES_OPAL_H_ +#pragma once #include @@ -73,4 +72,4 @@ int opal_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int opal_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NODES_OPAL_H_ @} */ +/** @} */ \ No newline at end of file diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 00a80d7b9..948301b0c 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -14,8 +14,7 @@ * @{ *********************************************************************************/ -#ifndef _NODES_SOCKET_H_ -#define _NODES_SOCKET_H_ +#pragma once #include #include @@ -109,4 +108,4 @@ char * socket_print_addr(struct sockaddr *saddr); */ int socket_parse_addr(const char *str, struct sockaddr *sa, enum socket_layer layer, int flags); -#endif /** _NODES_SOCKET_H_ @} */ +/** @} */ \ No newline at end of file diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index a0bacdcc2..4017230c3 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -15,9 +15,7 @@ * @{ *********************************************************************************/ - -#ifndef _NODES_WEBSOCKET_H_ -#define _NODES_WEBSOCKET_H_ +#pragma once #include "node.h" #include "pool.h" @@ -63,6 +61,8 @@ struct websocket_connection { qptr_t received; }; +int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + /** @see node_vtable::init */ int websocket_init(int argc, char * argv[], config_setting_t *cfg); @@ -84,4 +84,4 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_vtable::write */ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt); -#endif /** _NODES_WEBSOCKET_H_ @} */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/path.h b/include/villas/path.h index fb01e5d23..e09109a3e 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -12,8 +12,7 @@ * @{ *********************************************************************************/ -#ifndef _PATH_H_ -#define _PATH_H_ +#pragma once #include #include @@ -130,4 +129,4 @@ const char * path_name(struct path *p); /** Check if node is used as source or destination of a path. */ int path_uses_node(struct path *p, struct node *n); -#endif /** _PATH_H_ @} */ +/** @} */ \ No newline at end of file diff --git a/include/villas/plugin.h b/include/villas/plugin.h index 8c1c5a681..c67fe5b51 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _PLUGIN_H_ -#define _PLUGIN_H_ +#pragma once #include "hooks.h" #include "api.h" @@ -67,5 +66,3 @@ int plugin_load(struct plugin *p); int plugin_unload(struct plugin *p); int plugin_destroy(struct plugin *p); - -#endif /* _PLUGIN_H_ */ \ No newline at end of file diff --git a/include/villas/pool.h b/include/villas/pool.h index 49f2f1c9a..a36e292db 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -9,8 +9,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. */ -#ifndef _POOL_H_ -#define _POOL_H_ +#pragma once #include @@ -61,6 +60,4 @@ INLINE void * pool_get(struct pool *p) INLINE int pool_put(struct pool *p, void *buf) { return queue_push(&p->queue, buf); -} - -#endif /* _POOL_H_ */ \ No newline at end of file +} \ No newline at end of file diff --git a/include/villas/queue.h b/include/villas/queue.h index 40baf1f17..654ee4a49 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -31,9 +31,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _MPMC_QUEUE_H_ -#define _MPMC_QUEUE_H_ - #include #include @@ -82,6 +79,4 @@ int queue_pull(struct queue *q, void **ptr); int queue_push_many(struct queue *q, void *ptr[], size_t cnt); -int queue_pull_many(struct queue *q, void *ptr[], size_t cnt); - -#endif /* _MPMC_QUEUE_H_ */ \ No newline at end of file +int queue_pull_many(struct queue *q, void *ptr[], size_t cnt); \ No newline at end of file diff --git a/include/villas/sample.h b/include/villas/sample.h index ec58f8bd8..d3a349c22 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. */ -#ifndef _SAMPLE_H_ -#define _SAMPLE_H_ +#pragma once #include #include @@ -109,6 +108,4 @@ int sample_fprint(FILE *f, struct sample *s, int flags); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int sample_fscan(FILE *f, struct sample *s, int *flags); - -#endif /* _SAMPLE_H_ */ \ No newline at end of file +int sample_fscan(FILE *f, struct sample *s, int *flags); \ No newline at end of file diff --git a/include/villas/timing.h b/include/villas/timing.h index 20b2e6baf..1d00de4e7 100644 --- a/include/villas/timing.h +++ b/include/villas/timing.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _TIME_H_ -#define _TIME_H_ +#pragma once #include #include @@ -52,6 +51,4 @@ double time_delta(struct timespec *start, struct timespec *end); double time_to_double(struct timespec *ts); /** Convert double containing seconds after 1970 to timespec. */ -struct timespec time_from_double(double secs); - -#endif /* _TIMING_H_ */ \ No newline at end of file +struct timespec time_from_double(double secs); \ No newline at end of file diff --git a/include/villas/utils.h b/include/villas/utils.h index c1e7328a8..ee5b5c43c 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -7,8 +7,7 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#ifndef _UTILS_H_ -#define _UTILS_H_ +#pragma once #include #include @@ -239,6 +238,4 @@ static inline int log2i(long long x) { } /** Sleep with rdtsc */ -void rdtsc_sleep(uint64_t nanosecs, uint64_t start); - -#endif /* _UTILS_H_ */ \ No newline at end of file +void rdtsc_sleep(uint64_t nanosecs, uint64_t start); \ No newline at end of file From 8f15c763006d90dbc5ca4555c8694e2834c6b4fa Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:08:29 -0300 Subject: [PATCH 075/211] refactored kernel_is_rt() -> rt_is_preemptible() --- include/villas/kernel/kernel.h | 9 --------- include/villas/kernel/rt.h | 9 +++++++++ lib/kernel/kernel.c | 5 ----- lib/kernel/rt.c | 7 ++++++- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index b8bf1351d..f5bfeb442 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -20,15 +20,6 @@ */ //int kernel_check_cap(cap_value_t cap): -/** Checks for realtime (PREEMPT_RT) patched kernel. - * - * See https://rt.wiki.kernel.org - * - * @retval 0 Kernel is patched. - * @reval <>0 Kernel is not patched. - */ -int kernel_is_rt(); - /** Get kernel cmdline parameter * * See https://www.kernel.org/doc/Documentation/kernel-parameters.txt diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index c4b5cd2bf..b6310ea55 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -11,3 +11,12 @@ int rt_init(int affinity, int priority); + +/** Checks for realtime (PREEMPT_RT) patched kernel. + * + * See https://rt.wiki.kernel.org + * + * @retval 0 Kernel is patched. + * @reval <>0 Kernel is not patched. + */ +int rt_is_preemptible(); \ No newline at end of file diff --git a/lib/kernel/kernel.c b/lib/kernel/kernel.c index b2c9b94cc..1e4cced6a 100644 --- a/lib/kernel/kernel.c +++ b/lib/kernel/kernel.c @@ -104,11 +104,6 @@ int kernel_has_version(int maj, int min) return version_cmp(¤t, &required) < 0; } -int kernel_is_rt() -{ - return access(SYSFS_PATH "/kernel/realtime", R_OK); -} - int kernel_get_cmdline_param(const char *param, char *buf, size_t len) { int ret; diff --git a/lib/kernel/rt.c b/lib/kernel/rt.c index fa06a11c1..e5202dba7 100644 --- a/lib/kernel/rt.c +++ b/lib/kernel/rt.c @@ -18,7 +18,7 @@ int rt_init(int affinity, int priority) int is_isol, is_rt, ret; /* Use FIFO scheduler with real time priority */ - is_rt = kernel_is_rt(); + is_rt = rt_is_preemptible(); if (is_rt) warn("We recommend to use an PREEMPT_RT patched kernel!"); @@ -75,4 +75,9 @@ int rt_init(int affinity, int priority) warn("You should use the 'affinity' setting to pin VILLASnode to dedicate CPU cores"); return 0; +} + +int rt_is_preemptible() +{ + return access(SYSFS_PATH "/kernel/realtime", R_OK); } \ No newline at end of file From 728347f3e2e2b973cd6b15add4702c6a616b019f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:11:18 -0300 Subject: [PATCH 076/211] vfio: removed dependency to dma module --- include/villas/kernel/vfio.h | 7 +++---- lib/kernel/vfio.c | 29 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index b03a5c4a4..4c662ad98 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -20,7 +20,6 @@ #define VFIO_DEV(x) "/dev/vfio/" x /* Forward declaration */ -struct dma_mem; struct pci_dev; struct vfio_group { @@ -53,7 +52,7 @@ struct vfio_container { int version; int extensions; - void *iova_next; /**< Next free IOVA address */ + uint64_t iova_next; /**< Next free IOVA address */ struct list groups; }; @@ -101,10 +100,10 @@ void vfio_dump(struct vfio_container *c); void * vfio_map_region(struct vfio_dev *d, int idx); /** Map VM to an IOVA, which is accessible by devices in the container */ -int vfio_map_dma(struct vfio_container *c, struct dma_mem *mem); +int vfio_map_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len); /** Unmap DMA memory */ -int vfio_unmap_dma(struct vfio_container *c, struct dma_mem *mem); +int vfio_unmap_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len); /** munmap() a region which has been mapped by vfio_map_region() */ int vfio_unmap_region(struct vfio_dev *d, int idx); \ No newline at end of file diff --git a/lib/kernel/vfio.c b/lib/kernel/vfio.c index 68e7e0b3d..c8915fd21 100644 --- a/lib/kernel/vfio.c +++ b/lib/kernel/vfio.c @@ -27,8 +27,6 @@ #include "kernel/vfio.h" #include "kernel/pci.h" -#include "fpga/dma.h" - static const char *vfio_pci_region_names[] = { "PCI_BAR0", // VFIO_PCI_BAR0_REGION_INDEX, "PCI_BAR1", // VFIO_PCI_BAR1_REGION_INDEX, @@ -568,25 +566,26 @@ int vfio_unmap_region(struct vfio_dev *d, int idx) return 0; } -int vfio_map_dma(struct vfio_container *c, struct dma_mem *mem) +int vfio_map_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len) { int ret; - if (mem->len & 0xFFF) { - mem->len += 0x1000; - mem->len &= ~0xFFF; + if (len & 0xFFF) { + len += 0x1000; + len &= ~0xFFF; } - if (mem->base_phys == (void *) -1) { - mem->base_phys = c->iova_next; - c->iova_next += mem->len; + /* Super stupid allocator */ + if (phys == -1) { + phys = c->iova_next; + c->iova_next += len; } struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(struct vfio_iommu_type1_dma_map), - .vaddr = (uint64_t) mem->base_virt, - .iova = (uint64_t) mem->base_phys, - .size = mem->len, + .vaddr = virt, + .iova = phys, + .size = len, .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE }; @@ -599,15 +598,15 @@ int vfio_map_dma(struct vfio_container *c, struct dma_mem *mem) return 0; } -int vfio_unmap_dma(struct vfio_container *c, struct dma_mem *mem) +int vfio_unmap_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len) { int ret; struct vfio_iommu_type1_dma_unmap dma_unmap = { .argsz = sizeof(struct vfio_iommu_type1_dma_unmap), .flags = 0, - .iova = (uint64_t) mem->base_phys, - .size = mem->len, + .iova = phys, + .size = len, }; ret = ioctl(c->fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap); From 7b31c89216604b00a6cc609e526d2b08f7aaca28 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:11:49 -0300 Subject: [PATCH 077/211] rt: splitted rt_init() --- include/villas/kernel/rt.h | 5 +- include/villas/kernel/vfio.h | 2 +- lib/kernel/rt.c | 119 ++++++++++++++++++++--------------- 3 files changed, 74 insertions(+), 52 deletions(-) diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index b6310ea55..c704735e4 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -9,8 +9,11 @@ #pragma once -int rt_init(int affinity, int priority); +int rt_init(struct cfg *cfg); +int rt_set_affinity(int affinity); + +int rt_set_priority(int priority); /** Checks for realtime (PREEMPT_RT) patched kernel. * diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 4c662ad98..6c7c2868b 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -19,7 +19,7 @@ #define VFIO_DEV(x) "/dev/vfio/" x -/* Forward declaration */ +/* Forward declarations */ struct pci_dev; struct vfio_group { diff --git a/lib/kernel/rt.c b/lib/kernel/rt.c index e5202dba7..e8cac2b08 100644 --- a/lib/kernel/rt.c +++ b/lib/kernel/rt.c @@ -9,71 +9,90 @@ #include #include "utils.h" +#include "cfg.h" + #include "kernel/kernel.h" #include "kernel/rt.h" -int rt_init(int affinity, int priority) +int rt_init(struct cfg *cfg) { INDENT - char isolcpus[255]; - int is_isol, is_rt, ret; + int is_rt; /* Use FIFO scheduler with real time priority */ is_rt = rt_is_preemptible(); if (is_rt) warn("We recommend to use an PREEMPT_RT patched kernel!"); + if (cfg->priority) + rt_set_priority(cfg->priority); + else + warn("You might want to use the 'priority' setting to increase VILLASnode's process priority"); + + if (cfg->affinity) + rt_set_affinity(cfg->affinity); + else + warn("You should use the 'affinity' setting to pin VILLASnode to dedicate CPU cores"); + + return 0; +} + +int rt_set_affinity(int affinity) +{ + char isolcpus[255]; + int is_isol, ret; + + /* Pin threads to CPUs by setting the affinity */ + cpu_set_t cset_pin, cset_isol, cset_non_isol; + + cpuset_from_integer(affinity, &cset_pin); + + is_isol = kernel_get_cmdline_param("isolcpus", isolcpus, sizeof(isolcpus)); + if (is_isol) { + warn("You should reserve some cores for VILLASnode (see 'isolcpus')"); + + CPU_ZERO(&cset_isol); + } + else { + ret = cpulist_parse(isolcpus, &cset_isol, 0); + if (ret) + error("Invalid isolcpus cmdline parameter: %s", isolcpus); + + CPU_XOR(&cset_non_isol, &cset_isol, &cset_pin); + if (CPU_COUNT(&cset_non_isol) > 0) { + char isol[128], pin[128]; + + cpulist_create(isol, sizeof(isol), &cset_isol); + cpulist_create(pin, sizeof(pin), &cset_pin); + + warn("Affinity setting includes cores which are not isolated: affinity=%s isolcpus=%s", pin, isol); + } + } + + char list[128]; + cpulist_create(list, sizeof(list), &cset_pin); + + ret = sched_setaffinity(0, sizeof(cpu_set_t), &cset_pin); + if (ret) + serror("Failed to set CPU affinity to %s", list); + + debug(LOG_KERNEL | 3, "Set affinity to %s", list); + + return 0; +} + +int rt_set_priority(int priority) +{ + int ret; struct sched_param param = { .sched_priority = priority }; - if (priority) { - ret = sched_setscheduler(0, SCHED_FIFO, ¶m); - if (ret) - serror("Failed to set real time priority"); - - debug(3, "Task priority set to %u", priority); - } - - if (affinity) { - /* Pin threads to CPUs by setting the affinity */ - cpu_set_t cset_pin, cset_isol, cset_non_isol; - - cpuset_from_integer(affinity, &cset_pin); - - is_isol = kernel_get_cmdline_param("isolcpus", isolcpus, sizeof(isolcpus)); - if (is_isol) { - warn("You should reserve some cores for VILLASnode (see 'isolcpus')"); - - CPU_ZERO(&cset_isol); - } - else { - ret = cpulist_parse(isolcpus, &cset_isol, 0); - if (ret) - error("Invalid isolcpus cmdline parameter: %s", isolcpus); - - CPU_XOR(&cset_non_isol, &cset_isol, &cset_pin); - if (CPU_COUNT(&cset_non_isol) > 0) { - char isol[128], pin[128]; - - cpulist_create(isol, sizeof(isol), &cset_isol); - cpulist_create(pin, sizeof(pin), &cset_pin); - - warn("Affinity setting includes cores which are not isolated: affinity=%s isolcpus=%s", pin, isol); - } - } - - char list[128]; - cpulist_create(list, sizeof(list), &cset_pin); - - ret = sched_setaffinity(0, sizeof(cpu_set_t), &cset_pin); - if (ret) - serror("Failed to set CPU affinity to %s", list); - - debug(3, "Set affinity to %s", list); - } - else - warn("You should use the 'affinity' setting to pin VILLASnode to dedicate CPU cores"); + ret = sched_setscheduler(0, SCHED_FIFO, ¶m); + if (ret) + serror("Failed to set real time priority"); + debug(LOG_KERNEL | 3, "Task priority set to %u", priority); + return 0; } From 32186d8426f4929053b8193f930c794f595d7ff3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:28:16 -0300 Subject: [PATCH 078/211] log: support more debug log facilities --- include/villas/log.h | 32 ++++++++++++++++++-------------- lib/log.c | 2 +- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/include/villas/log.h b/include/villas/log.h index 1fa7ead85..f88870329 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -32,23 +32,27 @@ * To be or-ed with the debug level */ enum log_facilities { - LOG_POOL = (1 << 8), - LOG_QUEUE = (1 << 9), - LOG_CONFIG = (1 << 10), - LOG_HOOK = (1 << 11), - LOG_PATH = (1 << 12), - LOG_MEM = (1 << 13), + LOG_POOL = (1L << 8), + LOG_QUEUE = (1L << 9), + LOG_CONFIG = (1L << 10), + LOG_HOOK = (1L << 11), + LOG_PATH = (1L << 12), + LOG_MEM = (1L << 13), + LOG_WEB = (1L << 14), + LOG_API = (1L << 15), + LOG_LOG = (1L << 16), + LOG_KERNEL = (1L << 17), /* Node-types */ - LOG_SOCKET = (1 << 16), - LOG_FILE = (1 << 17), - LOG_FPGA = (1 << 18), - LOG_NGSI = (1 << 19), - LOG_WEBSOCKET = (1 << 20), - LOG_OPAL = (1 << 21), + LOG_SOCKET = (1L << 32), + LOG_FILE = (1L << 33), + LOG_FPGA = (1L << 34), + LOG_NGSI = (1L << 35), + LOG_WEBSOCKET = (1L << 36), + LOG_OPAL = (1L << 37), /* Classes */ - LOG_NODE = (0xFF << 16), + LOG_NODE = (0xFFL << 32), LOG_ALL = ~0xFF }; @@ -92,7 +96,7 @@ void log_print(const char *lvl, const char *fmt, ...) void log_vprint(const char *lvl, const char *fmt, va_list va); /** Printf alike debug message with level. */ -void debug(int lvl, const char *fmt, ...) +void debug(long lvl, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); /** Print a horizontal line. */ diff --git a/lib/log.c b/lib/log.c index 74e8d1694..36979eb71 100644 --- a/lib/log.c +++ b/lib/log.c @@ -110,7 +110,7 @@ void line() log_print("", "\b" ACS("%.*s"), LOG_WIDTH, buf); } -void debug(int class, const char *fmt, ...) +void debug(long class, const char *fmt, ...) { va_list ap; From 9b2b2875841162cf027443e13f47de87933c1acc Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 09:29:04 -0300 Subject: [PATCH 079/211] log: OOP refactoring --- include/villas/log.h | 43 +++++++++++---- lib/log.c | 123 +++++++++++++++++++++++++++++++++---------- 2 files changed, 129 insertions(+), 37 deletions(-) diff --git a/include/villas/log.h b/include/villas/log.h index f88870329..66b2de1bf 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -56,6 +56,24 @@ enum log_facilities { LOG_ALL = ~0xFF }; +struct log { + struct timespec epoch; /**< A global clock used to prefix the log messages. */ + + /** Debug level used by the debug() macro. + * It defaults to V (defined by the Makefile) and can be + * overwritten by the 'debug' setting in the configuration file. */ + int level; + + /** Debug facilities used by the debug() macro. */ + int facilities; +}; + +/** Initialize log object */ +int log_init(struct log *l); + +/** Destroy log object */ +int log_destroy(struct log *l); + /** Change log indention for current thread. * * The argument level can be negative! @@ -69,23 +87,30 @@ int log_indent(int levels); */ void log_outdent(int *); -/** Set the verbosity level of debug messages. +/** Set logging facilities based on expression. * - * @param lvl The new debug level. - * @param fac The new mask for debug facilities. + * Currently we support two types of expressions: + * 1. A comma seperated list of logging facilities + * 2. A comma seperated list of logging facilities which is prefixes with an exclamation mark '!' + * + * The first case enables only faciltities which are in the list. + * The second case enables all faciltities with exception of those which are in the list. + * + * @param expression The expression + * @return The new facilties mask (see enum log_faciltities) */ -void log_setlevel(int lvl, int fac); +int log_set_facility_expression(struct log *l, const char *expression); -/** Reset the wallclock of debug messages. */ -void log_init(); +/** Parse logging configuration. */ +int log_parse(struct log *l, config_setting_t *cfg); /** Logs variadic messages to stdout. * * @param lvl The log level * @param fmt The format string (printf alike) */ -void log_print(const char *lvl, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); +void log_print(struct log *l, const char *lvl, const char *fmt, ...) + __attribute__ ((format(printf, 3, 4))); /** Logs variadic messages to stdout. * @@ -93,7 +118,7 @@ void log_print(const char *lvl, const char *fmt, ...) * @param fmt The format string (printf alike) * @param va The variadic argument list (see stdarg.h) */ -void log_vprint(const char *lvl, const char *fmt, va_list va); +void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list va); /** Printf alike debug message with level. */ void debug(long lvl, const char *fmt, ...) diff --git a/lib/log.c b/lib/log.c index 36979eb71..47ac93479 100644 --- a/lib/log.c +++ b/lib/log.c @@ -23,16 +23,27 @@ #include "OpalPrint.h" #endif -/** Debug level used by the debug() macro. - * It defaults to V (defined by the Makefile) and can be - * overwritten by the 'debug' setting in the configuration file. */ -static unsigned level = V; +static struct log *log; -/** Debug facilities used by the debug() macro. */ -static unsigned facilities = ~0; - -/** A global clock used to prefix the log messages. */ -static struct timespec epoch; +/** List of debug facilities as strings */ +static const char *facilities_strs[] = { + "pool", /* LOG_POOL */ + "queue", /* LOG_QUEUE */ + "config", /* LOG_CONFIG */ + "hook", /* LOG_HOOK */ + "path", /* LOG_PATH */ + "mem", /* LOG_MEM */ + "web", /* LOG_WEB */ + "api", /* LOG_API */ + + /* Node-types */ + "socket", /* LOG_SOCKET */ + "file", /* LOG_FILE */ + "fpga", /* LOG_FPGA */ + "ngsi", /* LOG_NGSI */ + "websocket", /* LOG_WEBSOCKET */ + "opal" /* LOG_OPAL */ +}; #ifdef __GNUC__ /** The current log indention level (per thread!). */ @@ -51,34 +62,78 @@ void log_outdent(int *old) } #endif -void log_setlevel(int lvl, int fac) +int log_set_facility_expression(struct log *l, const char *expression) { - level = lvl; - debug(10, "Switched to debug level %u", level); + char *copy, *facility_str; + + enum { + NORMAL, + NEGATE + } mode; + + if (strlen(expression) <= 0) + return -1; + + if (expression[0] == '!') { + mode = NEGATE; + l->facilities = ~0xFF; + } + else { + mode = NORMAL; + l->facilities = 0; + } + + copy = strdup(expression); + facility_str = strtok(copy, ","); + + while (facility_str != NULL) { + for (int i = 0; i < ARRAY_LEN(facilities_strs); i++) { + if (strcmp(facilities_strs[i], facility_str)) { + switch (mode) { + case NORMAL: l->facilities |= (1 << (i+8)); + case NEGATE: l->facilities &= ~(1 << (i+8)); + } + } + } + + facility_str = strtok(NULL, ","); + } + + free(copy); + + return l->facilities; } -void log_init() +int log_init(struct log *l) { - epoch = time_now(); - debug(10, "Debug clock resetted"); + l->epoch = time_now(); + l->level = V; + l->facilities = LOG_ALL; + + debug(LOG_LOG | 10, "Log sub-system intialized"); + + /* Register this log instance globally */ + log = l; + + return 0; } -void log_print(const char *lvl, const char *fmt, ...) +void log_print(struct log *l, const char *lvl, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - log_vprint(lvl, fmt, ap); + log_vprint(l, lvl, fmt, ap); va_end(ap); } -void log_vprint(const char *lvl, const char *fmt, va_list ap) +void log_vprint(struct log *l, const char *lvl, const char *fmt, va_list ap) { struct timespec ts = time_now(); char *buf = alloc(512); /* Timestamp */ - strcatf(&buf, "%10.3f ", time_delta(&epoch, &ts)); + strcatf(&buf, "%10.3f ", time_delta(&l->epoch, &ts)); /* Severity */ strcatf(&buf, "%5s ", lvl); @@ -102,12 +157,24 @@ void log_vprint(const char *lvl, const char *fmt, va_list ap) free(buf); } +int log_parse(struct log *l, config_setting_t *cfg) +{ + const char *facilities; + + config_setting_lookup_int(cfg, "level", &l->level); + + if (config_setting_lookup_string(cfg, "facilties", &facilities)) + log_set_facility_expression(l, facilities); + + return 0; +} + void line() { char buf[LOG_WIDTH]; memset(buf, 0x71, sizeof(buf)); - log_print("", "\b" ACS("%.*s"), LOG_WIDTH, buf); + log_print(log, "", "\b" ACS("%.*s"), LOG_WIDTH, buf); } void debug(long class, const char *fmt, ...) @@ -117,9 +184,9 @@ void debug(long class, const char *fmt, ...) int lvl = class & 0xFF; int fac = class & ~0xFF; - if (((fac == 0) || (fac & facilities)) && (lvl <= level)) { + if (((fac == 0) || (fac & log->facilities)) && (lvl <= log->level)) { va_start(ap, fmt); - log_vprint(LOG_LVL_DEBUG, fmt, ap); + log_vprint(log, LOG_LVL_DEBUG, fmt, ap); va_end(ap); } } @@ -129,7 +196,7 @@ void info(const char *fmt, ...) va_list ap; va_start(ap, fmt); - log_vprint(LOG_LVL_INFO, fmt, ap); + log_vprint(log, LOG_LVL_INFO, fmt, ap); va_end(ap); } @@ -138,7 +205,7 @@ void warn(const char *fmt, ...) va_list ap; va_start(ap, fmt); - log_vprint(LOG_LVL_WARN, fmt, ap); + log_vprint(log, LOG_LVL_WARN, fmt, ap); va_end(ap); } @@ -147,7 +214,7 @@ void stats(const char *fmt, ...) va_list ap; va_start(ap, fmt); - log_vprint(LOG_LVL_STATS, fmt, ap); + log_vprint(log, LOG_LVL_STATS, fmt, ap); va_end(ap); } @@ -156,7 +223,7 @@ void error(const char *fmt, ...) va_list ap; va_start(ap, fmt); - log_vprint(LOG_LVL_ERROR, fmt, ap); + log_vprint(log, LOG_LVL_ERROR, fmt, ap); va_end(ap); die(); @@ -171,7 +238,7 @@ void serror(const char *fmt, ...) vstrcatf(&buf, fmt, ap); va_end(ap); - log_print(LOG_LVL_ERROR, "%s: %m (%u)", buf, errno); + log_print(log, LOG_LVL_ERROR, "%s: %m (%u)", buf, errno); free(buf); die(); @@ -186,7 +253,7 @@ void cerror(config_setting_t *cfg, const char *fmt, ...) vstrcatf(&buf, fmt, ap); va_end(ap); - log_print(LOG_LVL_ERROR, "%s in %s:%u", buf, + log_print(log, LOG_LVL_ERROR, "%s in %s:%u", buf, config_setting_source_file(cfg) ? config_setting_source_file(cfg) : "(stdio)", From 2b83fef2ce626d02fe3aadebf2f25e0ae432f31f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 16 Feb 2017 13:32:22 -0300 Subject: [PATCH 080/211] removed a bunch of non-needed include files (found by include-what-you-need.org) --- lib/cfg.c | 1 - lib/kernel/if.c | 3 --- lib/kernel/pci.c | 1 - lib/kernel/rt.c | 2 ++ lib/kernel/vfio.c | 2 -- lib/msg.c | 4 ---- lib/nodes/fpga.c | 3 --- lib/nodes/ngsi.c | 1 - lib/nodes/socket.c | 9 --------- src/fpga.c | 3 --- src/node.c | 2 -- src/pipe.c | 1 - tests/advio.c | 1 - 13 files changed, 2 insertions(+), 31 deletions(-) diff --git a/lib/cfg.c b/lib/cfg.c index d2781631e..4584bc1a9 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "utils.h" diff --git a/lib/kernel/if.c b/lib/kernel/if.c index 767831992..60c0af1ff 100644 --- a/lib/kernel/if.c +++ b/lib/kernel/if.c @@ -8,13 +8,10 @@ #include #include -#include #include -#include #include #include -#include #include "kernel/if.h" #include "kernel/tc.h" diff --git a/lib/kernel/pci.c b/lib/kernel/pci.c index 7ed1ba71c..bdd388f44 100644 --- a/lib/kernel/pci.c +++ b/lib/kernel/pci.c @@ -7,7 +7,6 @@ **********************************************************************************/ #include -#include #include #include diff --git a/lib/kernel/rt.c b/lib/kernel/rt.c index e8cac2b08..1c801abd1 100644 --- a/lib/kernel/rt.c +++ b/lib/kernel/rt.c @@ -7,7 +7,9 @@ *********************************************************************************/ #include +#include +#include "config.h" #include "utils.h" #include "cfg.h" diff --git a/lib/kernel/vfio.c b/lib/kernel/vfio.c index c8915fd21..d5fb7f9a7 100644 --- a/lib/kernel/vfio.c +++ b/lib/kernel/vfio.c @@ -12,10 +12,8 @@ #include #include #include -#include #include -#include #include #include "utils.h" diff --git a/lib/msg.c b/lib/msg.c index 70b277d31..7083307e5 100644 --- a/lib/msg.c +++ b/lib/msg.c @@ -6,10 +6,6 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#include -#include -#include - #ifdef __linux__ #include #elif defined(__PPC__) /* Xilinx toolchain */ diff --git a/lib/nodes/fpga.c b/lib/nodes/fpga.c index a7c65ff1d..0c71f3070 100644 --- a/lib/nodes/fpga.c +++ b/lib/nodes/fpga.c @@ -8,9 +8,6 @@ #include #include -#include -#include -#include #include "kernel/kernel.h" #include "kernel/pci.h" diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index 3aebd0368..e50b1c25c 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 48bffbc3e..707aa220b 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -6,18 +6,9 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#include #include - -#include #include -#include -#include - -#include #include -#include -#include #ifdef __linux__ #include diff --git a/src/fpga.c b/src/fpga.c index 46895c0f6..5492b5d6a 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -8,11 +8,8 @@ #include #include -#include #include -#include #include -#include #include #include diff --git a/src/node.c b/src/node.c index b4cf53cd7..6dbac04e8 100644 --- a/src/node.c +++ b/src/node.c @@ -7,10 +7,8 @@ *********************************************************************************/ #include -#include #include #include -#include #include "config.h" diff --git a/src/pipe.c b/src/pipe.c index 75ca559e9..465a915e3 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/tests/advio.c b/tests/advio.c index 3f3900a79..e3a63e6c6 100644 --- a/tests/advio.c +++ b/tests/advio.c @@ -5,7 +5,6 @@ #include #include -#include Test(advio, download) { From bc634ebcccbb4875fe437688525a555a9934167e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:31:42 -0500 Subject: [PATCH 081/211] first bunch of global state object --- config.h | 8 -- include/villas/cfg.h | 56 ++++++---- lib/cfg.c | 261 +++++++++++++++++++++++++++---------------- src/fpga.c | 2 +- src/node.c | 53 +++------ src/pipe.c | 2 +- src/test.c | 2 +- 7 files changed, 219 insertions(+), 165 deletions(-) diff --git a/config.h b/config.h index 3f9b62cca..6555fac32 100644 --- a/config.h +++ b/config.h @@ -61,11 +61,3 @@ /** AXI Bus frequency for all components * except RTDS AXI Stream bridge which runs at RTDS_HZ (100 Mhz) */ #define FPGA_AXI_HZ 125000000 // 125 MHz - -/** Global configuration */ -struct settings { - int priority; /**< Process priority (lower is better) */ - int affinity; /**< Process affinity of the server and all created threads */ - int debug; /**< Debug log level */ - double stats; /**< Interval for path statistics. Set to 0 to disable themo disable them. */ -}; diff --git a/include/villas/cfg.h b/include/villas/cfg.h index 2065d6d95..ae6f51a2d 100644 --- a/include/villas/cfg.h +++ b/include/villas/cfg.h @@ -15,37 +15,53 @@ #include -/* Forward declarations */ -struct list; -struct settings; +#include "list.h" +#include "api.h" +#include "web.h" +#include "log.h" + +/** Global configuration */ +struct cfg { + int priority; /**< Process priority (lower is better) */ + int affinity; /**< Process affinity of the server and all created threads */ + double stats; /**< Interval for path statistics. Set to 0 to disable them. */ + + struct list nodes; + struct list paths; + struct list plugins; + + struct log log; + struct api api; + struct web web; + + config_t *cfg; /**< Pointer to configuration file */ + json_t *json; /**< JSON representation of the same config. */ +}; /* Compatibility with libconfig < 1.5 */ #if (LIBCONFIG_VER_MAJOR <= 1) && (LIBCONFIG_VER_MINOR < 5) #define config_setting_lookup config_lookup_from #endif -/** Simple wrapper around libconfig's config_init() - * - * This allows us to avoid an additional library dependency to libconfig - * for the excuctables. They only have to depend on libvillas. - */ -void cfg_init(config_t *cfg); +/** Inititalize configuration object before parsing the configuration. */ +int cfg_init_pre(struct cfg *cfg); -/** Simple wrapper around libconfig's config_init() */ -void cfg_destroy(config_t *cfg); +/** Initialize after parsing the configuration file. */ +int cfg_init_post(struct cfg *cfg); -/** Parse config file and store settings in supplied struct settings. +int cfg_deinit(struct cfg *cfg); + +/** Desctroy configuration object. */ +int cfg_destroy(struct cfg *cfg); + +/** Parse config file and store settings in supplied struct cfg. * + * @param cfg A configuration object. * @param filename The path to the configration file (relative or absolute) - * @param cfg A initialized libconfig object - * @param set The global configuration structure - * @param nodes A linked list of nodes which should be parsed - * @param paths A linked list of paths which should be parsed * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int cfg_parse(const char *filename, config_t *cfg, struct settings *set, - struct list *nodes, struct list *paths); +int cfg_parse(struct cfg *cfg, const char *uri); /** Parse the global section of a configuration file. * @@ -54,7 +70,7 @@ int cfg_parse(const char *filename, config_t *cfg, struct settings *set, * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int cfg_parse_global(config_setting_t *cfg, struct settings *set); +int cfg_parse_global(config_setting_t *cfg, struct cfg *set); /** Parse a single path and add it to the global configuration. * @@ -66,7 +82,7 @@ int cfg_parse_global(config_setting_t *cfg, struct settings *set); * @retval <0 Error. Something went wrong. */ int cfg_parse_path(config_setting_t *cfg, - struct list *paths, struct list *nodes, struct settings *set); + struct list *paths, struct list *nodes, struct cfg *set); /** Parse an array or single node and checks if they exist in the "nodes" section. * diff --git a/lib/cfg.c b/lib/cfg.c index 4584bc1a9..f2abd1c11 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -17,134 +17,208 @@ #include "node.h" #include "path.h" #include "hooks.h" +#include "advio.h" +#include "web.h" +#include "log.h" +#include "api.h" +#include "plugin.h" -void cfg_init(config_t *cfg) +#include "kernel/rt.h" + +int cfg_init_pre(struct cfg *cfg) { - config_init(cfg); -} - -void cfg_destroy(config_t *cfg) -{ - config_destroy(cfg); -} - -int cfg_parse(const char *filename, config_t *cfg, struct settings *set, - struct list *nodes, struct list *paths) -{ - int ret = CONFIG_FALSE; - char *filename_cpy, *include_dir; - - config_init(cfg); - - filename_cpy = strdup(filename); - include_dir = dirname(filename_cpy); - - /* Setup libconfig */ - config_set_auto_convert(cfg, 1); - config_set_include_dir(cfg, include_dir); - - free(filename_cpy); + config_init(cfg->cfg); - if (strcmp("-", filename) == 0) - ret = config_read(cfg, stdin); - else if (access(filename, F_OK) != -1) - ret = config_read_file(cfg, filename); - else - error("Invalid configuration file name: %s", filename); + info("Inititliaze logging sub-system"); + log_init(&cfg->log); - if (ret != CONFIG_TRUE) { - error("Failed to parse configuration: %s in %s:%d", - config_error_text(cfg), - config_error_file(cfg) ? config_error_file(cfg) : filename, - config_error_line(cfg) - ); + list_init(&cfg->nodes); + list_init(&cfg->paths); + list_init(&cfg->plugins); + + return 0; +} + +int cfg_init_post(struct cfg *cfg) +{ + info("Initialize real-time sub-system"); + rt_init(cfg); + + info("Initialize hook sub-system"); + hook_init(cfg); + + info("Initialize API sub-system"); + api_init(&cfg->api, cfg); + + info("Initialize web sub-system"); + web_init(&cfg->web, &cfg->api); + + return 0; +} + +int cfg_deinit(struct cfg *cfg) +{ + info("De-initializing node types"); + list_foreach(struct node_type *vt, &node_types) { INDENT + node_deinit(vt); } + + info("De-initializing web interface"); + web_deinit(&cfg->web); + + info("De-initialize API"); + api_deinit(&cfg->api); + + return 0; +} - config_setting_t *cfg_root = config_root_setting(cfg); +int cfg_destroy(struct cfg *cfg) +{ + config_destroy(cfg->cfg); + + web_destroy(&cfg->web); + log_destroy(&cfg->log); + api_destroy(&cfg->api); + + list_destroy(&cfg->plugins, (dtor_cb_t) plugin_destroy, false); + list_destroy(&cfg->paths, (dtor_cb_t) path_destroy, true); + list_destroy(&cfg->nodes, (dtor_cb_t) node_destroy, true); + + return 0; +} + +int cfg_parse(struct cfg *cfg, const char *uri) +{ + config_setting_t *cfg_root, *cfg_nodes, *cfg_paths, *cfg_plugins, *cfg_logging; + + int ret = CONFIG_FALSE; + + if (uri) { + /* Setup libconfig */ + config_set_auto_convert(cfg->cfg, 1); + + FILE *f; + AFILE *af; + + /* Via stdin */ + if (strcmp("-", uri) == 0) { + af = NULL; + f = stdin; + } + /* Local file? */ + else if (access(uri, F_OK) != -1) { + /* Setup libconfig include path. + * This is only supported for local files */ + char *uri_cpy = strdup(uri); + char *include_dir = dirname(uri_cpy); + + config_set_include_dir(cfg->cfg, include_dir); + + free(uri_cpy); + + af = NULL; + f = fopen(uri, "r"); + } + /* Use advio (libcurl) to fetch the config from a remote */ + else { + af = afopen(uri, "r", ADVIO_MEM); + f = af ? af->file : NULL; + } + + /* Check if file could be loaded / opened */ + if (!f) + error("Failed to open configuration from: %s", uri); + + /* Parse config */ + ret = config_read(cfg->cfg, f); + if (ret != CONFIG_TRUE) + error("Failed to parse configuration: %s in %s:%d", config_error_text(cfg->cfg), uri, config_error_line(cfg->cfg)); + + /* Close configuration file */ + if (af) + afclose(af); + else + fclose(f); + } + else + warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); /* Parse global settings */ - if (set) { - if (!cfg_root || !config_setting_is_group(cfg_root)) - error("Missing global section in config file: %s", filename); + cfg_root = config_root_setting(cfg->cfg); + if (cfg_root) { + if (!config_setting_is_group(cfg_root)) + warn("Missing global section in config file."); - cfg_parse_global(cfg_root, set); + cfg_parse_global(cfg_root, cfg); + } + + /* Parse logging settings */ + cfg_logging = config_setting_get_member(cfg_root, "logging"); + if (cfg_logging) { + if (!config_setting_is_group(cfg_logging)) + cerror(cfg_logging, "Setting 'logging' must be a group."); + + log_parse(&cfg->log, cfg_logging); + } + + /* Parse plugins */ + cfg_plugins = config_setting_get_member(cfg_root, "plugins"); + if (cfg_plugins) { + if (!config_setting_is_array(cfg_plugins)) + cerror(cfg_plugins, "Setting 'plugins' must be a list of strings"); + + for (int i = 0; i < config_setting_length(cfg_plugins); i++) { + struct config_setting_t *cfg_plugin = config_setting_get_elem(cfg_plugins, i); + + struct plugin plugin; + + plugin_parse(&plugin, cfg_plugin); + } } /* Parse nodes */ - if (nodes) { - config_setting_t *cfg_nodes = config_setting_get_member(cfg_root, "nodes"); - if (!cfg_nodes || !config_setting_is_group(cfg_nodes)) - error("Missing node section in config file: %s", filename); + cfg_nodes = config_setting_get_member(cfg_root, "nodes"); + if (cfg_nodes) { + if (!config_setting_is_group(cfg_nodes)) + warn("Setting 'nodes' must be a group with node name => group mappings."); for (int i = 0; i < config_setting_length(cfg_nodes); i++) { config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i); - cfg_parse_node(cfg_node, nodes, set); + cfg_parse_node(cfg_node, &cfg->nodes, cfg); } } /* Parse paths */ - if (paths) { - config_setting_t *cfg_paths = config_setting_get_member(cfg_root, "paths"); - if (!cfg_paths || !config_setting_is_list(cfg_paths)) - error("Missing path section in config file: %s", filename); + cfg_paths = config_setting_get_member(cfg_root, "paths"); + if (cfg_paths) { + if (!config_setting_is_list(cfg_paths)) + warn("Setting 'paths' must be a list."); for (int i = 0; i < config_setting_length(cfg_paths); i++) { config_setting_t *cfg_path = config_setting_get_elem(cfg_paths, i); - cfg_parse_path(cfg_path, paths, nodes, set); + cfg_parse_path(cfg_path, &cfg->paths, &cfg->nodes, cfg); } } return 0; } -int cfg_parse_plugins(config_setting_t *cfg) +int cfg_parse_global(config_setting_t *cfg, struct cfg *set) { - if (!config_setting_is_array(cfg)) - cerror(cfg, "Setting 'plugins' must be a list of strings"); - - for (int i = 0; i < config_setting_length(cfg); i++) { - void *handle; - const char *path; - - path = config_setting_get_string_elem(cfg, i); - if (!path) - cerror(cfg, "Setting 'plugins' must be a list of strings"); - - handle = dlopen(path, RTLD_NOW); - if (!handle) - error("Failed to load plugin %s", dlerror()); - } - - return 0; -} - -int cfg_parse_global(config_setting_t *cfg, struct settings *set) -{ - config_setting_t *cfg_plugins; - if (!config_setting_lookup_int(cfg, "affinity", &set->affinity)) set->affinity = 0; if (!config_setting_lookup_int(cfg, "priority", &set->priority)) set->priority = 0; - if (!config_setting_lookup_int(cfg, "debug", &set->debug)) - set->debug = V; - if (!config_setting_lookup_float(cfg, "stats", &set->stats)) set->stats = 0; - - cfg_plugins = config_setting_get_member(cfg, "plugins"); - if (cfg_plugins) - cfg_parse_plugins(cfg_plugins); - - log_setlevel(set->debug, -1); return 0; } int cfg_parse_path(config_setting_t *cfg, - struct list *paths, struct list *nodes, struct settings *set) + struct list *paths, struct list *nodes, struct cfg *set) { config_setting_t *cfg_out, *cfg_hook; const char *in; @@ -203,11 +277,6 @@ int cfg_parse_path(config_setting_t *cfg, if (!config_setting_lookup_float(cfg, "rate", &p->rate)) p->rate = 0; /* disabled */ - if (!IS_POW2(p->queuelen)) { - p->queuelen = LOG2_CEIL(p->queuelen); - warn("Queue length should always be a power of 2. Adjusting to %d", p->queuelen); - } - p->cfg = cfg; list_push(paths, p); @@ -276,9 +345,9 @@ int cfg_parse_nodelist(config_setting_t *cfg, struct list *list, struct list *al return list_length(list); } -int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *set) +int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct cfg *set) { - const char *type, *name; + const char *type; int ret; struct node *n; @@ -287,16 +356,14 @@ int cfg_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *s /* Required settings */ if (!config_setting_lookup_string(cfg, "type", &type)) cerror(cfg, "Missing node type"); - - name = config_setting_name(cfg); vt = list_lookup(&node_types, type); if (!vt) cerror(cfg, "Invalid type for node '%s'", config_setting_name(cfg)); n = node_create(vt); - - n->name = name; + + n->name = config_setting_name(cfg); n->cfg = cfg; ret = node_parse(n, cfg); diff --git a/src/fpga.c b/src/fpga.c index 5492b5d6a..221e41b81 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -26,7 +26,7 @@ int fpga_benchmarks(int argc, char *argv[], struct fpga *f); int fpga_tests(int argc, char *argv[], struct fpga *f); -struct settings settings; +struct cfg settings; void usage(char *name) { diff --git a/src/node.c b/src/node.c index 6dbac04e8..29528e072 100644 --- a/src/node.c +++ b/src/node.c @@ -23,32 +23,21 @@ #include "opal.h" #endif -struct list paths; /**< List of paths */ -struct list nodes; /**< List of nodes */ - -static config_t config; /**< libconfig handle */ -struct settings settings; /**< The global configuration */ +struct cfg config; static void quit() { info("Stopping paths"); - list_foreach(struct path *p, &paths) { INDENT + list_foreach(struct path *p, &config.paths) { INDENT path_stop(p); } info("Stopping nodes"); - list_foreach(struct node *n, &nodes) { INDENT + list_foreach(struct node *n, &config.nodes) { INDENT node_stop(n); } - info("De-initializing node types"); - list_foreach(struct node_type *vt, &node_types) { INDENT - node_deinit(vt); - } - - /* Freeing dynamically allocated memory */ - list_destroy(&paths, (dtor_cb_t) path_destroy, false); - list_destroy(&nodes, (dtor_cb_t) node_destroy, false); + cfg_deinit(&config); cfg_destroy(&config); info(GRN("Goodbye!")); @@ -103,9 +92,6 @@ int main(int argc, char *argv[]) #endif usage(argv[0]); - char *configfile = (argc == 2) ? argv[1] : "opal-shmem.conf"; - - log_init(); info("This is VILLASnode %s (built on %s, %s)", BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__))); @@ -113,32 +99,26 @@ int main(int argc, char *argv[]) if (kernel_has_version(KERNEL_VERSION_MAJ, KERNEL_VERSION_MIN)) error("Your kernel version is to old: required >= %u.%u", KERNEL_VERSION_MAJ, KERNEL_VERSION_MIN); - /* Initialize lists */ - list_init(&paths); - list_init(&nodes); - - info("Parsing configuration"); - cfg_parse(configfile, &config, &settings, &nodes, &paths); - - info("Initialize real-time system"); - rt_init(settings.affinity, settings.priority); - info("Initialize signals"); signals_init(); - info("Initialize hook sub-system"); - hook_init(&nodes, &paths, &settings); + info("Parsing configuration"); + cfg_init_pre(&config); + + cfg_parse(&config, uri); + + cfg_init_post(&config); info("Initialize node types"); list_foreach(struct node_type *vt, &node_types) { INDENT int refs = list_length(&vt->instances); if (refs > 0) - node_init(vt, argc, argv, config_root_setting(&config)); + node_init(vt, argc, argv, config_root_setting(config.cfg)); } info("Starting nodes"); - list_foreach(struct node *n, &nodes) { INDENT - int refs = list_count(&paths, (cmp_cb_t) path_uses_node, n); + list_foreach(struct node *n, &config.nodes) { INDENT + int refs = list_count(&config.paths, (cmp_cb_t) path_uses_node, n); if (refs > 0) node_start(n); else @@ -146,7 +126,7 @@ int main(int argc, char *argv[]) } info("Starting paths"); - list_foreach(struct path *p, &paths) { INDENT + list_foreach(struct path *p, &config.paths) { INDENT if (p->enabled) { path_prepare(p); path_start(p); @@ -154,9 +134,8 @@ int main(int argc, char *argv[]) else warn("Path %s is disabled. Skipping...", path_name(p)); } - - /* Run! */ - if (settings.stats > 0) { + + if (config.stats > 0) hook_stats_header(); for (;;) { diff --git a/src/pipe.c b/src/pipe.c index 465a915e3..511deb87f 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -27,7 +27,7 @@ #include "config.h" static struct list nodes; /**< List of all nodes */ -static struct settings settings; /**< The global configuration */ +static struct cfg settings; /**< The global configuration */ static config_t config; struct dir { diff --git a/src/test.c b/src/test.c index ef95b2c65..318a13450 100644 --- a/src/test.c +++ b/src/test.c @@ -22,7 +22,7 @@ #include "timing.h" #include "pool.h" -struct settings settings; /** Date: Sat, 18 Feb 2017 10:43:01 -0500 Subject: [PATCH 082/211] refactored dtor_cb_t to return an integer --- include/villas/hist.h | 2 +- include/villas/list.h | 4 ++-- include/villas/node.h | 2 +- include/villas/path.h | 2 +- lib/hist.c | 4 +++- lib/list.c | 4 +++- lib/node.c | 4 +++- lib/nodes/ngsi.c | 12 ++++++++---- lib/path.c | 28 +++++++++++++++------------- lib/pool.c | 2 ++ 10 files changed, 39 insertions(+), 25 deletions(-) diff --git a/include/villas/hist.h b/include/villas/hist.h index fefd3a728..289affa78 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -44,7 +44,7 @@ struct hist { void hist_create(struct hist *h, double start, double end, double resolution); /** Free the dynamically allocated memory. */ -void hist_destroy(struct hist *h); +int hist_destroy(struct hist *h); /** Reset all counters and values back to zero. */ void hist_reset(struct hist *h); diff --git a/include/villas/list.h b/include/villas/list.h index 2e3e5ec6c..26d10fbaf 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -40,7 +40,7 @@ * * @param data A pointer to the data which should be freed. */ -typedef void (*dtor_cb_t)(void *); +typedef int (*dtor_cb_t)(void *); /** Callback to search or sort a list. */ typedef int (*cmp_cb_t)(const void *, const void *); @@ -65,7 +65,7 @@ void list_init(struct list *l); * @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed. * @param l A pointer to the list data structure. */ -void list_destroy(struct list *l, dtor_cb_t dtor, bool free); +int list_destroy(struct list *l, dtor_cb_t dtor, bool free); /** Append an element to the end of the list */ void list_push(struct list *l, void *p); diff --git a/include/villas/node.h b/include/villas/node.h index af24a35cb..19111cec4 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -198,7 +198,7 @@ struct node * node_create(struct node_type *vt); * * @see node_type::destroy */ -void node_destroy(struct node *n); +int node_destroy(struct node *n); /** Start operation of a node. * diff --git a/include/villas/path.h b/include/villas/path.h index e09109a3e..6aec9ed5c 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -85,7 +85,7 @@ void path_init(struct path *p); * * @param i A pointer to the path structure. */ -void path_destroy(struct path *p); +int path_destroy(struct path *p); /** Initialize pool queue and hooks. * diff --git a/lib/hist.c b/lib/hist.c index 8f29f6597..89da433e5 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -30,9 +30,11 @@ void hist_create(struct hist *h, double low, double high, double resolution) hist_reset(h); } -void hist_destroy(struct hist *h) +int hist_destroy(struct hist *h) { free(h->data); + + return 0; } void hist_put(struct hist *h, double value) diff --git a/lib/list.c b/lib/list.c index aa87553de..77f6f3fd5 100644 --- a/lib/list.c +++ b/lib/list.c @@ -42,7 +42,7 @@ void list_init(struct list *l) l->array = NULL; } -void list_destroy(struct list *l, dtor_cb_t destructor, bool release) +int list_destroy(struct list *l, dtor_cb_t destructor, bool release) { pthread_mutex_lock(&l->lock); @@ -62,6 +62,8 @@ void list_destroy(struct list *l, dtor_cb_t destructor, bool release) pthread_mutex_unlock(&l->lock); pthread_mutex_destroy(&l->lock); + + return 0; } void list_push(struct list *l, void *p) diff --git a/lib/node.c b/lib/node.c index b4aa9dc02..9a4284e04 100644 --- a/lib/node.c +++ b/lib/node.c @@ -193,7 +193,7 @@ struct node * node_create(struct node_type *vt) return n; } -void node_destroy(struct node *n) +int node_destroy(struct node *n) { if (n->_vt->destroy) n->_vt->destroy(n); @@ -203,4 +203,6 @@ void node_destroy(struct node *n) free(n->_vd); free(n->_name); free(n); + + return 0; } diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index e50b1c25c..d675eb056 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -429,26 +429,30 @@ char * ngsi_print(struct node *n) i->endpoint, i->timeout, list_length(&i->mapping)); } -static void ngsi_destroy_metadata(struct ngsi_metadata *meta) +static int ngsi_metadata_destroy(struct ngsi_metadata *meta) { free(meta->value); free(meta->name); free(meta->type); + + return 0; } -static void ngsi_destroy_attribute(struct ngsi_attribute *attr) +static int ngsi_attribute_destroy(struct ngsi_attribute *attr) { free(attr->name); free(attr->type); - list_destroy(&attr->metadata, (dtor_cb_t) ngsi_destroy_metadata, true); + list_destroy(&attr->metadata, (dtor_cb_t) ngsi_metadata_destroy, true); + + return 0; } int ngsi_destroy(struct node *n) { struct ngsi *i = n->_vd; - list_destroy(&i->mapping, (dtor_cb_t) ngsi_destroy_attribute, true); + list_destroy(&i->mapping, (dtor_cb_t) ngsi_attribute_destroy, true); return 0; } diff --git a/lib/path.c b/lib/path.c index a1693f2b1..d860ceac1 100644 --- a/lib/path.c +++ b/lib/path.c @@ -197,6 +197,21 @@ void path_init(struct path *p) p->state = PATH_CREATED; } +int path_destroy(struct path *p) +{ + hook_run(p, NULL, 0, HOOK_DEINIT); /* Release memory */ + + list_destroy(&p->destinations, NULL, false); + list_destroy(&p->hooks, NULL, true); + + queue_destroy(&p->queue); + pool_destroy(&p->pool); + + free(p->_name); + + return 0; +} + int path_prepare(struct path *p) { int ret; @@ -226,19 +241,6 @@ int path_prepare(struct path *p) return 0; } -void path_destroy(struct path *p) -{ - hook_run(p, NULL, 0, HOOK_DEINIT); /* Release memory */ - - list_destroy(&p->destinations, NULL, false); - list_destroy(&p->hooks, NULL, true); - - queue_destroy(&p->queue); - pool_destroy(&p->pool); - - free(p->_name); -} - int path_uses_node(struct path *p, struct node *n) { return (p->in == n) || list_contains(&p->destinations, n) ? 0 : 1; } diff --git a/lib/pool.c b/lib/pool.c index d84f24c81..9d3c7f0b6 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -43,4 +43,6 @@ int pool_destroy(struct pool *p) queue_destroy(&p->queue); return memory_free(p->mem, p->buffer, p->len); + + return 0; } \ No newline at end of file From 7de25683d744d168148d70138fd395199045fd47 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:43:58 -0500 Subject: [PATCH 083/211] fpga: refactored VILLASfpga node type --- include/villas/fpga/card.h | 63 ++++ include/villas/fpga/dma.h | 68 ----- include/villas/fpga/ip.h | 128 ++++---- include/villas/fpga/{ => ips}/dft.h | 20 +- include/villas/fpga/ips/dma.h | 74 +++++ include/villas/fpga/{ => ips}/fifo.h | 17 +- include/villas/fpga/{ => ips}/intc.h | 21 +- include/villas/fpga/{ => ips}/model.h | 27 +- include/villas/fpga/{ => ips}/rtds_axis.h | 17 +- include/villas/fpga/{ => ips}/switch.h | 23 +- include/villas/fpga/{ => ips}/timer.h | 13 +- include/villas/fpga/vlnv.h | 39 +++ lib/fpga/Makefile.inc | 6 +- lib/fpga/card.c | 184 ++++++++++++ lib/fpga/ip.c | 61 +--- lib/fpga/ips/Makefile.inc | 6 + lib/fpga/{ => ips}/dft.c | 23 +- lib/fpga/{ => ips}/dma.c | 50 ++-- lib/fpga/{ => ips}/fifo.c | 33 ++- lib/fpga/{ => ips}/intc.c | 30 +- lib/fpga/{ => ips}/model.c | 49 ++-- lib/fpga/{ => ips}/rtds_axis.c | 12 +- lib/fpga/{ => ips}/switch.c | 36 ++- lib/fpga/{ => ips}/timer.c | 12 +- lib/fpga/vlnv.c | 45 +++ lib/nodes/fpga.c | 337 +++++++--------------- src/fpga-bench-overruns.c | 2 +- src/fpga-bench.c | 6 +- src/fpga-tests.c | 32 +- 29 files changed, 839 insertions(+), 595 deletions(-) create mode 100644 include/villas/fpga/card.h delete mode 100644 include/villas/fpga/dma.h rename include/villas/fpga/{ => ips}/dft.h (68%) create mode 100644 include/villas/fpga/ips/dma.h rename include/villas/fpga/{ => ips}/fifo.h (65%) rename include/villas/fpga/{ => ips}/intc.h (63%) rename include/villas/fpga/{ => ips}/model.h (82%) rename include/villas/fpga/{ => ips}/rtds_axis.h (88%) rename include/villas/fpga/{ => ips}/switch.h (63%) rename include/villas/fpga/{ => ips}/timer.h (73%) create mode 100644 include/villas/fpga/vlnv.h create mode 100644 lib/fpga/card.c create mode 100644 lib/fpga/ips/Makefile.inc rename lib/fpga/{ => ips}/dft.c (87%) rename lib/fpga/{ => ips}/dma.c (89%) rename lib/fpga/{ => ips}/fifo.c (78%) rename lib/fpga/{ => ips}/intc.c (86%) rename lib/fpga/{ => ips}/model.c (89%) rename lib/fpga/{ => ips}/rtds_axis.c (88%) rename lib/fpga/{ => ips}/switch.c (85%) rename lib/fpga/{ => ips}/timer.c (82%) create mode 100644 lib/fpga/vlnv.c diff --git a/include/villas/fpga/card.h b/include/villas/fpga/card.h new file mode 100644 index 000000000..8fa9815d4 --- /dev/null +++ b/include/villas/fpga/card.h @@ -0,0 +1,63 @@ +/** FPGA card + * + * This class represents a FPGA device. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Steffen Vogel + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#pragma once + +enum fpga_card_state { + FPGA_CARD_STATE_UNKOWN, + FPGA_CARD_STATE_RESETTED, + FPGA_CARD_STATE_INITIALIZED +}; + +struct fpga_card { + char *name; /**< The name of the FPGA card */ + + enum fpga_card_state state; /**< The state of this FPGA card. */ + + struct pci_dev filter; /**< Filter for PCI device. */ + struct vfio_dev vd; /**< VFIO device handle. */ + + int do_reset; /**< Reset VILLASfpga during startup? */ + int affinity; /**< Affinity for MSI interrupts */ + + struct list ips; /**< List of IP components on FPGA. */ + + char *map; /**< PCI BAR0 mapping for register access */ + + size_t maplen; + size_t dmalen; + + /* Some IP cores are special and referenced here */ + struct fpga_ip *intc; + struct fpga_ip *reset; + struct fpga_ip *sw; + + config_setting_t *cfg; +}; + +int fpga_card_parse(struct fpga_card *c, config_setting_t *cfg); + +/** Initialize FPGA card and its IP components. */ +int fpga_card_init(struct fpga_card *c); + +int fpga_card_destroy(struct fpga_card *c); + +/** Check if the FPGA card configuration is plausible. */ +int fpga_card_check(struct fpga_card *c); + +/** Reset the FPGA to a known state */ +int fpga_card_reset(struct fpga_card *c); + +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/dma.h b/include/villas/fpga/dma.h deleted file mode 100644 index 172d80dba..000000000 --- a/include/villas/fpga/dma.h +++ /dev/null @@ -1,68 +0,0 @@ -/** DMA related helper functions - * - * These functions present a simpler interface to Xilinx' DMA driver (XAxiDma_*) - * - * @file - * @author Steffen Vogel - * @copyright 2015-2016, Steffen Vogel - * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ - -#ifndef _FPGA_DMA_H_ -#define _FPGA_DMA_H_ - -#include -#include -#include - -#include - -#define FPGA_DMA_BASEADDR 0x00000000 -#define FPGA_DMA_BOUNDARY 0x1000 -#define FPGA_DMA_BD_OFFSET 0xC0000000 -#define FPGA_DMA_BD_SIZE (32 << 20) // 32 MB - -#define XAXIDMA_SR_SGINCL_MASK 0x00000008 - -struct dma_mem { - char *base_virt; - char *base_phys; - size_t len; -}; - -struct dma { - XAxiDma inst; - - struct dma_mem bd; -}; - -struct ip; - -int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b); - -int dma_alloc(struct ip *c, struct dma_mem *mem, size_t len, int flags); -int dma_free(struct ip *c, struct dma_mem *mem); - -int dma_write(struct ip *c, char *buf, size_t len); -int dma_read(struct ip *c, char *buf, size_t len); -int dma_read_complete(struct ip *c, char **buf, size_t *len); -int dma_write_complete(struct ip *c, char **buf, size_t *len); - -int dma_sg_write(struct ip *c, char *buf, size_t len); -int dma_sg_read(struct ip *c, char *buf, size_t len); - -int dma_sg_write_complete(struct ip *c, char **buf, size_t *len); -int dma_sg_read_complete(struct ip *c, char **buf, size_t *len); - -int dma_simple_read(struct ip *c, char *buf, size_t len); -int dma_simple_write(struct ip *c, char *buf, size_t len); - -int dma_simple_read_complete(struct ip *c, char **buf, size_t *len); -int dma_simple_write_complete(struct ip *c, char **buf, size_t *len); - -int dma_ping_pong(struct ip *c, char *src, char *dst, size_t len); - -int dma_init(struct ip *c); - -#endif /* _FPGA_DMA_H_ */ \ No newline at end of file diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index 72a7cda7d..fb0e94a88 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -1,62 +1,73 @@ -#ifndef _FPGA_IP_H_ -#define _FPGA_IP_H_ +/** Interlectual Property component. + * + * This class represents a module within the FPGA. + * + * @file + * @author Steffen Vogel + * @copyright 2015-2016, Steffen Vogel + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#pragma once #include -#include -#include -#include -#include -#include - #include "utils.h" -#include "fpga/dma.h" -#include "fpga/switch.h" -#include "fpga/fifo.h" -#include "fpga/rtds_axis.h" -#include "fpga/timer.h" -#include "fpga/model.h" -#include "fpga/dft.h" -#include "fpga/intc.h" + #include "nodes/fpga.h" -extern struct list ip_types; /**< Table of existing FPGA IP core drivers */ +#include "fpga/vlnv.h" -enum ip_state { +#include "fpga/ips/dma.h" +#include "fpga/ips/switch.h" +#include "fpga/ips/fifo.h" +#include "fpga/ips/rtds_axis.h" +#include "fpga/ips/timer.h" +#include "fpga/ips/model.h" +#include "fpga/ips/dft.h" +#include "fpga/ips/intc.h" + +enum fpga_ip_state { IP_STATE_UNKNOWN, IP_STATE_INITIALIZED }; -struct ip_vlnv { - char *vendor; - char *library; - char *name; - char *version; +struct fpga_ip_type { + struct fpga_vlnv vlnv; + + enum { + FPGA_IP_TYPE_DATAMOVER, /**< A datamover IP exchanges streaming data between the FPGA and the CPU. */ + FPGA_IP_TYPE_MODEL, /**< A model IP simulates a system on the FPGA. */ + FPGA_IP_TYPE_MATH, /**< A math IP performs some kind of mathematical operation on the streaming data */ + FPGA_IP_TYPE_MISC, /**< Other IP components like timer, counters, interrupt conctrollers or routing. */ + FPGA_IP_TYPE_INTERFACE /**< A interface IP connects the FPGA to another system or controller. */ + } type; + + int (*parse)(struct fpga_ip *c); + int (*init)(struct fpga_ip *c); + int (*reset)(struct fpga_ip *c); + void (*dump)(struct fpga_ip *c); + void (*destroy)(struct fpga_ip *c); }; -struct ip_type { - struct ip_vlnv vlnv; +struct fpga_ip { + char *name; /**< Name of the FPGA IP component. */ + struct fpga_vlnv vlnv; /**< The Vendor, Library, Name, Version tag of the FPGA IP component. */ - int (*parse)(struct ip *c); - int (*init)(struct ip *c); - int (*reset)(struct ip *c); - void (*dump)(struct ip *c); - void (*destroy)(struct ip *c); -}; + enum fpga_ip_state state; /**< The current state of the FPGA IP component. */ -struct ip { - char *name; + struct fpga_ip_type *_vt; /**< Vtable containing FPGA IP type function pointers. */ - struct ip_vlnv vlnv; + uintptr_t baseaddr; /**< The baseadress of this FPGA IP component */ + uintptr_t baseaddr_axi4; /**< Used by AXI4 FIFO DM */ - uintptr_t baseaddr; - uintptr_t baseaddr_axi4; - - int port, irq; - - enum ip_state state; - - struct ip_type *_vt; + int port; /**< The port of the AXI4-Stream switch to which this FPGA IP component is connected. */ + int irq; /**< The interrupt number of the FPGA IP component. */ union { struct model model; @@ -66,33 +77,26 @@ struct ip { struct sw sw; struct dft dft; struct intc intc; - }; + }; /**< Specific private date per FPGA IP type. Depends on fpga_ip::_vt */ - struct fpga *card; + struct fpga_card *card; /**< The FPGA to which this IP instance belongs to. */ config_setting_t *cfg; }; -/** Return the first IP block in list \p l which matches the VLNV */ -struct ip * ip_vlnv_lookup(struct list *l, const char *vendor, const char *library, const char *name, const char *version); +/** Initialize IP instance. */ +int fpga_ip_init(struct fpga_ip *c); -/** Check if IP block \p c matched VLNV. */ -int ip_vlnv_cmp(struct ip_vlnv *a, struct ip_vlnv *b); +/** Release dynamic memory allocated by this IP instance. */ +int fpga_ip_destroy(struct fpga_ip *c); -/** Tokenizes VLNV \p vlnv and stores it into \p c */ -int ip_vlnv_parse(struct ip_vlnv *c, const char *vlnv); +/** Dump details about this IP instance to stdout. */ +void fpga_ip_dump(struct fpga_ip *c); -/** Release memory allocated by ip_vlnv_parse(). */ -void ip_vlnv_destroy(struct ip_vlnv *v); +/** Reset IP component to its initial state. */ +int fpga_ip_reset(struct fpga_ip *c); -int ip_init(struct ip *c); +/** Parse IP configuration from configuration file */ +int fpga_ip_parse(struct fpga_ip *c, config_setting_t *cfg); -void ip_destroy(struct ip *c); - -void ip_dump(struct ip *c); - -int ip_reset(struct ip *c); - -int ip_parse(struct ip *c, config_setting_t *cfg); - -#endif /* _FPGA_IP_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/dft.h b/include/villas/fpga/ips/dft.h similarity index 68% rename from include/villas/fpga/dft.h rename to include/villas/fpga/ips/dft.h index 52edfb37b..95edb9abf 100644 --- a/include/villas/fpga/dft.h +++ b/include/villas/fpga/ips/dft.h @@ -5,10 +5,13 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ - -#ifndef _FPGA_DFT_H_ -#define _FPGA_DFT_H_ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#pragma once #include @@ -24,11 +27,10 @@ struct dft { int decimation; }; -int dft_parse(struct ip *c); +int dft_parse(struct fpga_ip *c); -int dft_init(struct ip *c); +int dft_init(struct fpga_ip *c); -void dft_destroy(struct ip *c); +int dft_destroy(struct fpga_ip *c); - -#endif /* _FPGA_DFT_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/ips/dma.h b/include/villas/fpga/ips/dma.h new file mode 100644 index 000000000..ab6fffb10 --- /dev/null +++ b/include/villas/fpga/ips/dma.h @@ -0,0 +1,74 @@ +/** DMA related helper functions. + * + * These functions present a simpler interface to Xilinx' DMA driver (XAxiDma_*). + * + * @file + * @author Steffen Vogel + * @copyright 2015-2016, Steffen Vogel + * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#pragma once + +#include +#include +#include + +#include + +/* Forward declarations */ +struct fpga_ip; + +#define FPGA_DMA_BASEADDR 0x00000000 +#define FPGA_DMA_BOUNDARY 0x1000 +#define FPGA_DMA_BD_OFFSET 0xC0000000 +#define FPGA_DMA_BD_SIZE (32 << 20) // 32 MB + +#define XAXIDMA_SR_SGINCL_MASK 0x00000008 + +struct dma_mem { + char *base_virt; + char *base_phys; + size_t len; +}; + +struct dma { + XAxiDma inst; + + struct dma_mem bd; +}; + +struct ip; + +int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b); + +int dma_alloc(struct fpga_ip *c, struct dma_mem *mem, size_t len, int flags); +int dma_free(struct fpga_ip *c, struct dma_mem *mem); + +int dma_write(struct fpga_ip *c, char *buf, size_t len); +int dma_read(struct fpga_ip *c, char *buf, size_t len); +int dma_read_complete(struct fpga_ip *c, char **buf, size_t *len); +int dma_write_complete(struct fpga_ip *c, char **buf, size_t *len); + +int dma_sg_write(struct fpga_ip *c, char *buf, size_t len); +int dma_sg_read(struct fpga_ip *c, char *buf, size_t len); + +int dma_sg_write_complete(struct fpga_ip *c, char **buf, size_t *len); +int dma_sg_read_complete(struct fpga_ip *c, char **buf, size_t *len); + +int dma_simple_read(struct fpga_ip *c, char *buf, size_t len); +int dma_simple_write(struct fpga_ip *c, char *buf, size_t len); + +int dma_simple_read_complete(struct fpga_ip *c, char **buf, size_t *len); +int dma_simple_write_complete(struct fpga_ip *c, char **buf, size_t *len); + +int dma_ping_pong(struct fpga_ip *c, char *src, char *dst, size_t len); + +int dma_init(struct fpga_ip *c); + +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/fifo.h b/include/villas/fpga/ips/fifo.h similarity index 65% rename from include/villas/fpga/fifo.h rename to include/villas/fpga/ips/fifo.h index 1872fa488..4602ed36f 100644 --- a/include/villas/fpga/fifo.h +++ b/include/villas/fpga/ips/fifo.h @@ -7,10 +7,13 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ -#ifndef _FPGA_FIFO_H_ -#define _FPGA_FIFO_H_ +#pragma once #include @@ -26,10 +29,10 @@ struct fifo { /* Forward declaration */ struct ip; -int fifo_init(struct ip *c); +int fifo_init(struct fpga_ip *c); -ssize_t fifo_write(struct ip *c, char *buf, size_t len); +ssize_t fifo_write(struct fpga_ip *c, char *buf, size_t len); -ssize_t fifo_read(struct ip *c, char *buf, size_t len); +ssize_t fifo_read(struct fpga_ip *c, char *buf, size_t len); -#endif /* _FPGA_FIFO_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/intc.h b/include/villas/fpga/ips/intc.h similarity index 63% rename from include/villas/fpga/intc.h rename to include/villas/fpga/ips/intc.h index 626fe07d6..2449259b9 100644 --- a/include/villas/fpga/intc.h +++ b/include/villas/fpga/ips/intc.h @@ -4,10 +4,13 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ -#ifndef _FPGA_INTC_H_ -#define _FPGA_INTC_H_ +#pragma once #include @@ -25,14 +28,14 @@ struct intc { int flags[32]; /**< Mask of intc_flags */ }; -int intc_init(struct ip *c); +int intc_init(struct fpga_ip *c); -void intc_destroy(struct ip *c); +int intc_destroy(struct fpga_ip *c); -int intc_enable(struct ip *c, uint32_t mask, int poll); +int intc_enable(struct fpga_ip *c, uint32_t mask, int poll); -int intc_disable(struct ip *c, uint32_t mask); +int intc_disable(struct fpga_ip *c, uint32_t mask); -uint64_t intc_wait(struct ip *c, int irq); +uint64_t intc_wait(struct fpga_ip *c, int irq); -#endif /* _FPGA_INTC_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/model.h b/include/villas/fpga/ips/model.h similarity index 82% rename from include/villas/fpga/model.h rename to include/villas/fpga/ips/model.h index 5270d626a..a5387e6c7 100644 --- a/include/villas/fpga/model.h +++ b/include/villas/fpga/ips/model.h @@ -5,10 +5,13 @@ * @copyright 2016, Steffen Vogel * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - *********************************************************************************/ - -#ifndef _FPGA_MODEL_H_ -#define _FPGA_MODEL_H_ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#pragma once #include #include @@ -85,26 +88,26 @@ struct model_param { union model_param_value default_value; - struct ip *ip; /**< A pointer to the model structure to which this parameters belongs to. */ + struct fpga_ip *ip; /**< A pointer to the model structure to which this parameters belongs to. */ }; /** Initialize a model */ -int model_init(struct ip *c); +int model_init(struct fpga_ip *c); /** Parse model */ -int model_parse(struct ip *c); +int model_parse(struct fpga_ip *c); /** Destroy a model */ -void model_destroy(struct ip *c); +int model_destroy(struct fpga_ip *c); /** Print detailed information about the model to the screen. */ -void model_dump(struct ip *c); +void model_dump(struct fpga_ip *c); /** Add a new parameter to the model */ -void model_param_add(struct ip *c, const char *name, enum model_param_direction dir, enum model_param_type type); +void model_param_add(struct fpga_ip *c, const char *name, enum model_param_direction dir, enum model_param_type type); /** Remove an existing parameter by its name */ -int model_param_remove(struct ip *c, const char *name); +int model_param_remove(struct fpga_ip *c, const char *name); /** Read a model parameter. * @@ -123,4 +126,4 @@ int model_param_write(struct model_param *p, double v); int model_param_update(struct model_param *p, struct model_param *u); -#endif /* _FPGA_MODEL_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/rtds_axis.h b/include/villas/fpga/ips/rtds_axis.h similarity index 88% rename from include/villas/fpga/rtds_axis.h rename to include/villas/fpga/ips/rtds_axis.h index ecd6072fc..c4b8a907f 100644 --- a/include/villas/fpga/rtds_axis.h +++ b/include/villas/fpga/ips/rtds_axis.h @@ -5,12 +5,15 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ -#ifndef _FPGA_RTDS_AXIS_H_ -#define _FPGA_RTDS_AXIS_H_ +#pragma once -/* Forward declaration */ +/* Forward declarations */ struct ip; #define RTDS_HZ 100000000 // 100 MHz @@ -38,8 +41,8 @@ struct ip; /* Control register bits */ #define RTDS_AXIS_CR_DISABLE_LINK 0 /**< Disable SFP TX when set */ -void rtds_axis_dump(struct ip *c); +void rtds_axis_dump(struct fpga_ip *c); -double rtds_axis_dt(struct ip *c); +double rtds_axis_dt(struct fpga_ip *c); -#endif /* _FPGA_RTDS_AXIS_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/switch.h b/include/villas/fpga/ips/switch.h similarity index 63% rename from include/villas/fpga/switch.h rename to include/villas/fpga/ips/switch.h index fe109ad83..39de68b70 100644 --- a/include/villas/fpga/switch.h +++ b/include/villas/fpga/ips/switch.h @@ -7,10 +7,13 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ -#ifndef _FPGA_SWITCH_H_ -#define _FPGA_SWITCH_H_ +#pragma once #include @@ -33,17 +36,17 @@ struct sw { struct ip; -int switch_init(struct ip *c); +int switch_init(struct fpga_ip *c); /** Initialize paths which have been parsed by switch_parse() */ -int switch_init_paths(struct ip *c); +int switch_init_paths(struct fpga_ip *c); -void switch_destroy(struct ip *c); +int switch_destroy(struct fpga_ip *c); -int switch_parse(struct ip *c); +int switch_parse(struct fpga_ip *c); -int switch_connect(struct ip *c, struct ip *mi, struct ip *si); +int switch_connect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si); -int switch_disconnect(struct ip *c, struct ip *mi, struct ip *si); +int switch_disconnect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si); -#endif /* _FPGA_SWITCH_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/timer.h b/include/villas/fpga/ips/timer.h similarity index 73% rename from include/villas/fpga/timer.h rename to include/villas/fpga/ips/timer.h index 27cc37b98..2a83ce1d2 100644 --- a/include/villas/fpga/timer.h +++ b/include/villas/fpga/ips/timer.h @@ -7,13 +7,18 @@ * @copyright 2015-2016, Steffen Vogel * This file is part of S2SS. All Rights Reserved. Proprietary and confidential. * Unauthorized copying of this file, via any medium is strictly prohibited. - **********************************************************************************/ + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ -#ifndef _FPGA_TIMER_H_ -#define _FPGA_TIMER_H_ +#pragma once + +#include struct timer { XTmrCtr inst; }; -#endif /* _FPGA_TIMER_H_ */ \ No newline at end of file +/** @} */ \ No newline at end of file diff --git a/include/villas/fpga/vlnv.h b/include/villas/fpga/vlnv.h new file mode 100644 index 000000000..2abf2721e --- /dev/null +++ b/include/villas/fpga/vlnv.h @@ -0,0 +1,39 @@ +/** Vendor, Library, Name, Version (VLNV) tag. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ +/** + * @addtogroup fpga VILLASfpga + * @{ + */ + +#ifndef _FPGA_VLNV_H_ +#define _FPGA_VLNV_H_ + +/* Forward declarations */ +struct list; + +struct fpga_vlnv { + char *vendor; + char *library; + char *name; + char *version; +}; + +/** Return the first IP block in list \p l which matches the VLNV */ +struct fpga_ip * fpga_vlnv_lookup(struct list *l, struct fpga_vlnv *v); + +/** Check if IP block \p c matched VLNV. */ +int fpga_vlnv_cmp(struct fpga_vlnv *a, struct fpga_vlnv *b); + +/** Tokenizes VLNV \p vlnv and stores it into \p c */ +int fpga_vlnv_parse(struct fpga_vlnv *c, const char *vlnv); + +/** Release memory allocated by fpga_vlnv_parse(). */ +int fpga_vlnv_destroy(struct fpga_vlnv *v); + +#endif /** _FPGA_VLNV_H_ @} */ \ No newline at end of file diff --git a/lib/fpga/Makefile.inc b/lib/fpga/Makefile.inc index 3881fd813..01a3188c8 100644 --- a/lib/fpga/Makefile.inc +++ b/lib/fpga/Makefile.inc @@ -1,6 +1,8 @@ # Enable VILLASfpga support when libxil is available ifndef WITHOUT_FPGA ifeq ($(shell pkg-config libxil; echo $$?),0) - LIB_SRCS += $(wildcard lib/fpga/*.c) + LIB_SRCS += $(wildcard lib/fpga/*.c) endif -endif \ No newline at end of file +endif + +-include lib/fpga/ip/Makefile.inc \ No newline at end of file diff --git a/lib/fpga/card.c b/lib/fpga/card.c new file mode 100644 index 000000000..02c5d5de6 --- /dev/null +++ b/lib/fpga/card.c @@ -0,0 +1,184 @@ +#include + +#include "config.h" + +#include "kernel/pci.h" +#include "kernel/vfio.h" + +#include "fpga/ip.h" +#include "fpga/card.h" + +int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *vc) +{ + int ret; + + struct pci_dev *pdev; + + fpga_card_check(c); + + if (c->state == FPGA_CARD_STATE_INITIALIZED) + return 0; + + /* Search for FPGA card */ + pdev = pci_lookup_device(pci, &c->filter); + if (!pdev) + error("Failed to find PCI device"); + + /* Attach PCIe card to VFIO container */ + ret = vfio_pci_attach(&c->vd, vc, pdev); + if (ret) + error("Failed to attach VFIO device"); + + /* Map PCIe BAR */ + c->map = vfio_map_region(&c->vd, VFIO_PCI_BAR0_REGION_INDEX); + if (c->map == MAP_FAILED) + serror("Failed to mmap() BAR0"); + + /* Enable memory access and PCI bus mastering for DMA */ + ret = vfio_pci_enable(&c->vd); + if (ret) + serror("Failed to enable PCI device"); + + /* Reset system? */ + if (c->do_reset) { + /* Reset / detect PCI device */ + ret = vfio_pci_reset(&c->vd); + if (ret) + serror("Failed to reset PCI device"); + + ret = fpga_card_reset(c); + if (ret) + error("Failed to reset FGPA card"); + } + + /* Initialize IP cores */ + list_foreach(struct fpga_ip *i, &c->ips) { + ret = fpga_ip_init(i); + if (ret) + error("Failed to initalize IP core: %s (%u)", i->name, ret); + } + + return 0; +} + +int fpga_card_parse(struct fpga_card *c, config_setting_t *cfg) +{ + int ret; + const char *slot, *id, *err; + config_setting_t *cfg_ips, *cfg_slot, *cfg_id; + + /* Default values */ + c->filter.id.vendor = FPGA_PCI_VID_XILINX; + c->filter.id.device = FPGA_PCI_PID_VFPGA; + + c->name = config_setting_name(cfg); + c->state = FPGA_CARD_STATE_UNKOWN; + + if (!config_setting_lookup_int(cfg, "affinity", &c->affinity)) + c->affinity = 0; + + if (!config_setting_lookup_bool(cfg, "do_reset", &c->do_reset)) + c->do_reset = 0; + + cfg_slot = config_setting_get_member(cfg, "slot"); + if (cfg_slot) { + slot = config_setting_get_string(cfg_slot); + if (slot) { + ret = pci_dev_parse_slot(&c->filter, slot, &err); + if (ret) + cerror(cfg_slot, "Failed to parse PCI slot: %s", err); + } + else + cerror(cfg_slot, "PCI slot must be a string"); + } + + cfg_id = config_setting_get_member(cfg, "id"); + if (cfg_id) { + id = config_setting_get_string(cfg_id); + if (id) { + ret = pci_dev_parse_id(&c->filter, (char*) id, &err); + if (ret) + cerror(cfg_id, "Failed to parse PCI id: %s", err); + } + else + cerror(cfg_slot, "PCI ID must be a string"); + } + + cfg_ips = config_setting_get_member(cfg, "ips"); + if (!cfg_ips) + cerror(cfg, "FPGA configuration is missing ips section"); + + for (int i = 0; i < config_setting_length(cfg_ips); i++) { + config_setting_t *cfg_ip = config_setting_get_elem(cfg_ips, i); + + struct fpga_ip ip = { + .card = c + }; + + ret = fpga_ip_parse(&ip, cfg_ip); + if (ret) + cerror(cfg_ip, "Failed to parse VILLASfpga IP core"); + + list_push(&c->ips, memdup(&ip, sizeof(ip))); + } + + c->cfg = cfg; + + return 0; +} + +int fpga_card_check(struct fpga_card *c) +{ + /* Check FPGA configuration */ + c->reset = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_gpio", NULL }); + if (!c->reset) + error("FPGA is missing a reset controller"); + + c->intc = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL }); + if (!c->intc) + error("FPGA is missing a interrupt controller"); + + c->sw = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axis_interconnect", NULL }); + if (!c->sw) + warn("FPGA is missing an AXI4-Stream switch"); + + return 0; +} + +int fpga_card_destroy(struct fpga_card *c) +{ + list_destroy(&c->ips, (dtor_cb_t) fpga_ip_destroy, true); + + return 0; +} + +int fpga_card_reset(struct fpga_card *c) +{ + int ret; + char state[4096]; + + /* Save current state of PCI configuration space */ + ret = pread(c->vd.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40); + if (ret != sizeof(state)) + return -1; + + uint32_t *rst_reg = (uint32_t *) (c->map + c->reset->baseaddr); + + debug(3, "FPGA: reset"); + rst_reg[0] = 1; + + usleep(100000); + + /* Restore previous state of PCI configuration space */ + ret = pwrite(c->vd.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40); + if (ret != sizeof(state)) + return -1; + + /* After reset the value should be zero again */ + if (rst_reg[0]) + return -2; + + c->state = FPGA_CARD_STATE_RESETTED; + + return 0; +} \ No newline at end of file diff --git a/lib/fpga/ip.c b/lib/fpga/ip.c index 4bb87f07c..9fcf16ae0 100644 --- a/lib/fpga/ip.c +++ b/lib/fpga/ip.c @@ -1,48 +1,9 @@ -#include -#include - #include #include "log.h" +#include "plugin.h" -#include "fpga/ip.h" -#include "fpga/intc.h" -#include "fpga/fifo.h" -#include "nodes/fpga.h" - -#include "config.h" - -int ip_vlnv_cmp(struct ip_vlnv *a, struct ip_vlnv *b) -{ - return ((!a->vendor || !b->vendor || !strcmp(a->vendor, b->vendor )) && - (!a->library || !b->library || !strcmp(a->library, b->library)) && - (!a->name || !b->name || !strcmp(a->name, b->name )) && - (!a->version || !b->version || !strcmp(a->version, b->version))) ? 0 : 1; -} - -int ip_vlnv_parse(struct ip_vlnv *c, const char *vlnv) -{ - char *tmp = strdup(vlnv); - - c->vendor = strdup(strtok(tmp, ":")); - c->library = strdup(strtok(NULL, ":")); - c->name = strdup(strtok(NULL, ":")); - c->version = strdup(strtok(NULL, ":")); - - free(tmp); - - return 0; -} - -void ip_vlnv_destroy(struct ip_vlnv *v) -{ - free(c->vendor); - free(c->library); - free(c->name); - free(c->version); -} - -int ip_init(struct ip *c) +int fpga_ip_init(struct fpga_ip *c) { int ret; @@ -58,22 +19,24 @@ int ip_init(struct ip *c) return ret; } -int ip_reset(struct ip *c) +int fpga_ip_reset(struct fpga_ip *c) { debug(3, "Reset IP core: %s", c->name); return c->_vt && c->_vt->reset ? c->_vt->reset(c) : 0; } -void ip_destroy(struct ip *c) +int fpga_ip_destroy(struct fpga_ip *c) { if (c->_vt && c->_vt->destroy) c->_vt->destroy(c); - ip_vlnv_destroy(c->vlnv); + fpga_vlnv_destroy(&c->vlnv); + + return 0; } -void ip_dump(struct ip *c) +void fpga_ip_dump(struct fpga_ip *c) { info("IP %s: vlnv=%s:%s:%s:%s baseaddr=%#jx, irq=%d, port=%d", c->name, c->vlnv.vendor, c->vlnv.library, c->vlnv.name, c->vlnv.version, @@ -83,7 +46,7 @@ void ip_dump(struct ip *c) c->_vt->dump(c); } -int ip_parse(struct ip *c, config_setting_t *cfg) +int fpga_ip_parse(struct fpga_ip *c, config_setting_t *cfg) { int ret; const char *vlnv; @@ -98,15 +61,15 @@ int ip_parse(struct ip *c, config_setting_t *cfg) if (!config_setting_lookup_string(cfg, "vlnv", &vlnv)) cerror(cfg, "IP %s is missing the VLNV identifier", c->name); - ret = ip_vlnv_parse(&c->vlnv, vlnv); + ret = fpga_vlnv_parse(&c->vlnv, vlnv); if (ret) cerror(cfg, "Failed to parse VLNV identifier"); /* Try to find matching IP type */ list_foreach(struct plugin *l, &plugins) { if (l->type == PLUGIN_TYPE_FPGA_IP && - !ip_vlnv_match(&c->ip.vlnv, &l->ip.vlnv)) { - c->_vt = t; + !fpga_vlnv_cmp(&c->vlnv, &l->ip.vlnv)) { + c->_vt = &l->ip; break; } } diff --git a/lib/fpga/ips/Makefile.inc b/lib/fpga/ips/Makefile.inc new file mode 100644 index 000000000..54f1d72eb --- /dev/null +++ b/lib/fpga/ips/Makefile.inc @@ -0,0 +1,6 @@ +# Enable VILLASfpga support when libxil is available +ifndef WITHOUT_FPGA +ifeq ($(shell pkg-config libxil; echo $$?),0) + LIB_SRCS += $(wildcard lib/fpga/ips/*.c) +endif +endif \ No newline at end of file diff --git a/lib/fpga/dft.c b/lib/fpga/ips/dft.c similarity index 87% rename from lib/fpga/dft.c rename to lib/fpga/ips/dft.c index db5b4be16..652621f6b 100644 --- a/lib/fpga/dft.c +++ b/lib/fpga/ips/dft.c @@ -11,9 +11,10 @@ #include "plugin.h" #include "fpga/ip.h" -#include "fpga/dft.h" +#include "fpga/card.h" +#include "fpga/ips/dft.h" -int dft_parse(struct ip *c) +int dft_parse(struct fpga_ip *c) { struct dft *dft = &c->dft; @@ -44,13 +45,16 @@ int dft_parse(struct ip *c) return 0; } -int dft_init(struct ip *c) +int dft_init(struct fpga_ip *c) { int ret; + + struct fpga_card *f = c->card; struct dft *dft = &c->dft; + XHls_dft *xdft = &dft->inst; XHls_dft_Config xdft_cfg = { - .Ctrl_BaseAddress = (uintptr_t) c->card->map + c->baseaddr + .Ctrl_BaseAddress = (uintptr_t) f->map + c->baseaddr }; ret = XHls_dft_CfgInitialize(xdft, &xdft_cfg); @@ -74,7 +78,7 @@ int dft_init(struct ip *c) return 0; } -void dft_destroy(struct ip *c) +int dft_destroy(struct fpga_ip *c) { struct dft *dft = &c->dft; XHls_dft *xdft = &dft->inst; @@ -85,6 +89,8 @@ void dft_destroy(struct ip *c) free(dft->fharmonics); dft->fharmonics = NULL; } + + return 0; } static struct plugin p = { @@ -92,10 +98,11 @@ static struct plugin p = { .description = "Perfom Discrete Fourier Transforms with variable number of harmonics on the FPGA", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "hls", "hls_dft", NULL }, - .init = dft_init, + .vlnv = { "acs.eonerc.rwth-aachen.de", "hls", "hls_dft", NULL }, + .type = FPGA_IP_TYPE_MATH, + .init = dft_init, .destroy = dft_destroy, - .parse = dft_parse + .parse = dft_parse } }; diff --git a/lib/fpga/dma.c b/lib/fpga/ips/dma.c similarity index 89% rename from lib/fpga/dma.c rename to lib/fpga/ips/dma.c index ebfdbadc7..3ca509dab 100644 --- a/lib/fpga/dma.c +++ b/lib/fpga/ips/dma.c @@ -17,8 +17,9 @@ #include "plugin.h" #include "utils.h" -#include "fpga/dma.h" #include "fpga/ip.h" +#include "fpga/card.h" +#include "fpga/ips/dma.h" int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b) { @@ -36,9 +37,11 @@ int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b) return 0; } -int dma_alloc(struct ip *c, struct dma_mem *mem, size_t len, int flags) +int dma_alloc(struct fpga_ip *c, struct dma_mem *mem, size_t len, int flags) { int ret; + + struct fpga_card *f = c->card; /* Align to next bigger page size chunk */ if (len & 0xFFF) { @@ -52,18 +55,18 @@ int dma_alloc(struct ip *c, struct dma_mem *mem, size_t len, int flags) if (mem->base_virt == MAP_FAILED) return -1; - ret = vfio_map_dma(c->card->vd.group->container, mem); + ret = vfio_map_dma(f->vd.group->container, (uint64_t) mem->base_virt, (uint64_t) mem->base_phys, mem->len); if (ret) return -2; return 0; } -int dma_free(struct ip *c, struct dma_mem *mem) +int dma_free(struct fpga_ip *c, struct dma_mem *mem) { int ret; - ret = vfio_unmap_dma(c->card->vd.group->container, mem); + ret = vfio_unmap_dma(c->card->vd.group->container, (uint64_t) mem->base_virt, (uint64_t) mem->base_phys, mem->len); if (ret) return ret; @@ -74,7 +77,7 @@ int dma_free(struct ip *c, struct dma_mem *mem) return 0; } -int dma_ping_pong(struct ip *c, char *src, char *dst, size_t len) +int dma_ping_pong(struct fpga_ip *c, char *src, char *dst, size_t len) { int ret; @@ -97,7 +100,7 @@ int dma_ping_pong(struct ip *c, char *src, char *dst, size_t len) return 0; } -int dma_write(struct ip *c, char *buf, size_t len) +int dma_write(struct fpga_ip *c, char *buf, size_t len) { XAxiDma *xdma = &c->dma.inst; @@ -108,7 +111,7 @@ int dma_write(struct ip *c, char *buf, size_t len) : dma_simple_write(c, buf, len); } -int dma_read(struct ip *c, char *buf, size_t len) +int dma_read(struct fpga_ip *c, char *buf, size_t len) { XAxiDma *xdma = &c->dma.inst; @@ -119,7 +122,7 @@ int dma_read(struct ip *c, char *buf, size_t len) : dma_simple_read(c, buf, len); } -int dma_read_complete(struct ip *c, char **buf, size_t *len) +int dma_read_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; @@ -130,7 +133,7 @@ int dma_read_complete(struct ip *c, char **buf, size_t *len) : dma_simple_read_complete(c, buf, len); } -int dma_write_complete(struct ip *c, char **buf, size_t *len) +int dma_write_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; @@ -141,7 +144,7 @@ int dma_write_complete(struct ip *c, char **buf, size_t *len) : dma_simple_write_complete(c, buf, len); } -int dma_sg_write(struct ip *c, char *buf, size_t len) +int dma_sg_write(struct fpga_ip *c, char *buf, size_t len) { int ret, bdcnt; @@ -216,7 +219,7 @@ out: return -5; } -int dma_sg_read(struct ip *c, char *buf, size_t len) +int dma_sg_read(struct fpga_ip *c, char *buf, size_t len) { int ret, bdcnt; @@ -284,7 +287,7 @@ out: return -5; } -int dma_sg_write_complete(struct ip *c, char **buf, size_t *len) +int dma_sg_write_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma); @@ -313,7 +316,7 @@ int dma_sg_write_complete(struct ip *c, char **buf, size_t *len) return 0; } -int dma_sg_read_complete(struct ip *c, char **buf, size_t *len) +int dma_sg_read_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma); @@ -365,7 +368,7 @@ int dma_sg_read_complete(struct ip *c, char **buf, size_t *len) return 0; } -int dma_simple_read(struct ip *c, char *buf, size_t len) +int dma_simple_read(struct fpga_ip *c, char *buf, size_t len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma); @@ -401,7 +404,7 @@ int dma_simple_read(struct ip *c, char *buf, size_t len) return XST_SUCCESS; } -int dma_simple_write(struct ip *c, char *buf, size_t len) +int dma_simple_write(struct fpga_ip *c, char *buf, size_t len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma); @@ -438,7 +441,7 @@ int dma_simple_write(struct ip *c, char *buf, size_t len) return XST_SUCCESS; } -int dma_simple_read_complete(struct ip *c, char **buf, size_t *len) +int dma_simple_read_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma); @@ -459,7 +462,7 @@ int dma_simple_read_complete(struct ip *c, char **buf, size_t *len) return 0; } -int dma_simple_write_complete(struct ip *c, char **buf, size_t *len) +int dma_simple_write_complete(struct fpga_ip *c, char **buf, size_t *len) { XAxiDma *xdma = &c->dma.inst; XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma); @@ -535,7 +538,7 @@ static int dma_init_rings(XAxiDma *xdma, struct dma_mem *bd) return 0; } -int dma_init(struct ip *c) +int dma_init(struct fpga_ip *c) { int ret, sg; struct dma *dma = &c->dma; @@ -590,7 +593,7 @@ int dma_init(struct ip *c) return 0; } -int dma_reset(struct ip *c) +int dma_reset(struct fpga_ip *c) { XAxiDma_Reset(&c->dma.inst); @@ -602,9 +605,10 @@ static struct plugin p = { .description = "Transfer data streams between VILLASnode and VILLASfpga", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "xilinx.com", "ip", "axi_dma", NULL }, - .init = dma_init, - .reset = dma_reset + .vlnv = { "xilinx.com", "ip", "axi_dma", NULL }, + .type = FPGA_IP_TYPE_DATAMOVER, + .init = dma_init, + .reset = dma_reset } }; diff --git a/lib/fpga/fifo.c b/lib/fpga/ips/fifo.c similarity index 78% rename from lib/fpga/fifo.c rename to lib/fpga/ips/fifo.c index fab633588..d912b60e6 100644 --- a/lib/fpga/fifo.c +++ b/lib/fpga/ips/fifo.c @@ -14,18 +14,20 @@ #include "plugin.h" #include "fpga/ip.h" -#include "fpga/fifo.h" -#include "fpga/intc.h" +#include "fpga/card.h" +#include "fpga/ips/fifo.h" +#include "fpga/ips/intc.h" -int fifo_init(struct ip *c) +int fifo_init(struct fpga_ip *c) { - struct fifo *fifo = &c->fifo; - XLlFifo *xfifo = &fifo->inst; - int ret; + struct fpga_card *f = c->card; + struct fifo *fifo = &c->fifo; + + XLlFifo *xfifo = &fifo->inst; XLlFifo_Config fifo_cfg = { - .BaseAddress = (uintptr_t) c->card->map + c->baseaddr, + .BaseAddress = (uintptr_t) f->map + c->baseaddr, .Axi4BaseAddress = (uintptr_t) c->card->map + fifo->baseaddr_axi4, .Datainterface = (fifo->baseaddr_axi4 != -1) ? 1 : 0 /* use AXI4 for Data, AXI4-Lite for control */ }; @@ -39,7 +41,7 @@ int fifo_init(struct ip *c) return 0; } -ssize_t fifo_write(struct ip *c, char *buf, size_t len) +ssize_t fifo_write(struct fpga_ip *c, char *buf, size_t len) { XLlFifo *fifo = &c->fifo.inst; uint32_t tdfv; @@ -54,7 +56,7 @@ ssize_t fifo_write(struct ip *c, char *buf, size_t len) return len; } -ssize_t fifo_read(struct ip *c, char *buf, size_t len) +ssize_t fifo_read(struct fpga_ip *c, char *buf, size_t len) { XLlFifo *fifo = &c->fifo.inst; @@ -75,7 +77,7 @@ ssize_t fifo_read(struct ip *c, char *buf, size_t len) return nextlen; } -int fifo_parse(struct ip *c) +int fifo_parse(struct fpga_ip *c) { struct fifo *fifo = &c->fifo; @@ -89,7 +91,7 @@ int fifo_parse(struct ip *c) return 0; } -int fifo_reset(struct ip *c) +int fifo_reset(struct fpga_ip *c) { XLlFifo_Reset(&c->fifo.inst); @@ -101,10 +103,11 @@ static struct plugin p = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }, - .init = fifo_init, - .parse = fifo_parse, - .reset = fifo_reset + .vlnv = { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }, + .type = FPGA_IP_TYPE_DATAMOVER, + .init = fifo_init, + .parse = fifo_parse, + .reset = fifo_reset } }; diff --git a/lib/fpga/intc.c b/lib/fpga/ips/intc.c similarity index 86% rename from lib/fpga/intc.c rename to lib/fpga/ips/intc.c index 0e0e32b7d..6c9abf012 100644 --- a/lib/fpga/intc.c +++ b/lib/fpga/ips/intc.c @@ -18,13 +18,14 @@ #include "kernel/kernel.h" #include "fpga/ip.h" -#include "fpga/intc.h" +#include "fpga/card.h" +#include "fpga/ips/intc.h" -int intc_init(struct ip *c) +int intc_init(struct fpga_ip *c) { int ret; - struct fpga *f = c->card; + struct fpga_card *f = c->card; struct intc *intc = &c->intc; uintptr_t base = (uintptr_t) f->map + c->baseaddr; @@ -62,18 +63,20 @@ int intc_init(struct ip *c) return 0; } -void intc_destroy(struct ip *c) +int intc_destroy(struct fpga_ip *c) { - struct fpga *f = c->card; + struct fpga_card *f = c->card; struct intc *intc = &c->intc; vfio_pci_msi_deinit(&f->vd, intc->efds); + + return 0; } -int intc_enable(struct ip *c, uint32_t mask, int flags) +int intc_enable(struct fpga_ip *c, uint32_t mask, int flags) { + struct fpga_card *f = c->card; struct intc *intc = &c->intc; - struct fpga *f = c->card; uint32_t ier, imr; uintptr_t base = (uintptr_t) f->map + c->baseaddr; @@ -108,9 +111,9 @@ int intc_enable(struct ip *c, uint32_t mask, int flags) return 0; } -int intc_disable(struct ip *c, uint32_t mask) +int intc_disable(struct fpga_ip *c, uint32_t mask) { - struct fpga *f = c->card; + struct fpga_card *f = c->card; uintptr_t base = (uintptr_t) f->map + c->baseaddr; uint32_t ier = XIntc_In32(base + XIN_IER_OFFSET); @@ -120,10 +123,10 @@ int intc_disable(struct ip *c, uint32_t mask) return 0; } -uint64_t intc_wait(struct ip *c, int irq) +uint64_t intc_wait(struct fpga_ip *c, int irq) { + struct fpga_card *f = c->card; struct intc *intc = &c->intc; - struct fpga *f = c->card; uintptr_t base = (uintptr_t) f->map + c->baseaddr; @@ -154,8 +157,9 @@ static struct plugin p = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL }, - .init = intc_init, + .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL }, + .type = FPGA_IP_TYPE_MISC, + .init = intc_init, .destroy = intc_destroy } }; diff --git a/lib/fpga/model.c b/lib/fpga/ips/model.c similarity index 89% rename from lib/fpga/model.c rename to lib/fpga/ips/model.c index 6c7f8366f..9806cdeb9 100644 --- a/lib/fpga/model.c +++ b/lib/fpga/ips/model.c @@ -16,17 +16,22 @@ #include "plugin.h" #include "fpga/ip.h" -#include "fpga/model.h" +#include "fpga/card.h" +#include "fpga/ips/model.h" -static void model_param_destroy(struct model_param *p) +static int model_param_destroy(struct model_param *p) { free(p->name); + + return 0; } -static void model_info_destroy(struct model_info *i) +static int model_info_destroy(struct model_info *i) { free(i->field); free(i->value); + + return 0; } static uint32_t model_xsg_map_checksum(uint32_t *map, size_t len) @@ -130,7 +135,7 @@ static int model_xsg_map_read(uint32_t *map, size_t len, void *baseaddr) return i; } -int model_parse(struct ip *c) +int model_parse(struct fpga_ip *c) { struct model *m = &c->model; struct model_param p; @@ -188,7 +193,7 @@ static int model_init_from_xsg_map(struct model *m, void *baseaddr) return 0; } -int model_init(struct ip *c) +int model_init(struct fpga_ip *c) { int ret; struct model *m = &c->model; @@ -196,7 +201,7 @@ int model_init(struct ip *c) list_init(&m->parameters); list_init(&m->infos); - if (ip_vlnv_match(c, NULL, "sysgen", NULL, NULL)) + if (!fpga_vlnv_cmp(&c->vlnv, &(struct fpga_vlnv) { NULL, "sysgen", NULL, NULL })) ret = model_init_from_xsg_map(m, c->card->map + c->baseaddr); else ret = 0; @@ -217,7 +222,7 @@ int model_init(struct ip *c) return 0; } -void model_destroy(struct ip *c) +int model_destroy(struct fpga_ip *c) { struct model *m = &c->model; @@ -226,9 +231,11 @@ void model_destroy(struct ip *c) if (m->xsg.map != NULL) free(m->xsg.map); + + return 0; } -void model_dump(struct ip *c) +void model_dump(struct fpga_ip *c) { struct model *m = &c->model; @@ -264,7 +271,7 @@ void model_dump(struct ip *c) int model_param_read(struct model_param *p, double *v) { - struct ip *c = p->ip; + struct fpga_ip *c = p->ip; union model_param_value *ptr = (union model_param_value *) (c->card->map + c->baseaddr + p->offset); @@ -290,7 +297,7 @@ int model_param_read(struct model_param *p, double *v) int model_param_write(struct model_param *p, double v) { - struct ip *c = p->ip; + struct fpga_ip *c = p->ip; union model_param_value *ptr = (union model_param_value *) (c->card->map + c->baseaddr + p->offset); @@ -315,7 +322,7 @@ int model_param_write(struct model_param *p, double v) return 0; } -void model_param_add(struct ip *c, const char *name, enum model_param_direction dir, enum model_param_type type) +void model_param_add(struct fpga_ip *c, const char *name, enum model_param_direction dir, enum model_param_type type) { struct model *m = &c->model; struct model_param *p = alloc(sizeof(struct model_param)); @@ -327,7 +334,7 @@ void model_param_add(struct ip *c, const char *name, enum model_param_direction list_push(&m->parameters, p); } -int model_param_remove(struct ip *c, const char *name) +int model_param_remove(struct fpga_ip *c, const char *name) { struct model *m = &c->model; struct model_param *p; @@ -359,11 +366,12 @@ static struct plugin p_hls = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { NULL, "hls", NULL, NULL }, - .init = model_init, + .vlnv = { NULL, "hls", NULL, NULL }, + .type = FPGA_IP_TYPE_MODEL, + .init = model_init, .destroy = model_destroy, - .dump = model_dump, - .parse = model_parse + .dump = model_dump, + .parse = model_parse } }; @@ -374,11 +382,12 @@ static struct plugin p_sysgen = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { NULL, "sysgen", NULL, NULL }, - .init = model_init, + .vlnv = { NULL, "sysgen", NULL, NULL }, + .type = FPGA_IP_TYPE_MODEL, + .init = model_init, .destroy = model_destroy, - .dump = model_dump, - .parse = model_parse + .dump = model_dump, + .parse= model_parse } }; diff --git a/lib/fpga/rtds_axis.c b/lib/fpga/ips/rtds_axis.c similarity index 88% rename from lib/fpga/rtds_axis.c rename to lib/fpga/ips/rtds_axis.c index ebb2e1ef6..3bc9372ae 100644 --- a/lib/fpga/rtds_axis.c +++ b/lib/fpga/ips/rtds_axis.c @@ -13,9 +13,10 @@ #include "plugin.h" #include "fpga/ip.h" -#include "fpga/rtds_axis.h" +#include "fpga/card.h" +#include "fpga/ips/rtds_axis.h" -void rtds_axis_dump(struct ip *c) +void rtds_axis_dump(struct fpga_ip *c) { /* Check RTDS_Axis registers */ uint32_t *regs = (uint32_t *) (c->card->map + c->baseaddr); @@ -42,7 +43,7 @@ void rtds_axis_dump(struct ip *c) } } -double rtds_axis_dt(struct ip *c) +double rtds_axis_dt(struct fpga_ip *c) { uint32_t *regs = (uint32_t *) (c->card->map + c->baseaddr); uint16_t dt = regs[RTDS_AXIS_TS_PERIOD_OFFSET/4]; @@ -55,8 +56,9 @@ static struct plugin p = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }, - .dump = rtds_axis_dump + .vlnv = { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }, + .type = FPGA_IP_TYPE_INTERFACE, + .dump = rtds_axis_dump } }; diff --git a/lib/fpga/switch.c b/lib/fpga/ips/switch.c similarity index 85% rename from lib/fpga/switch.c rename to lib/fpga/ips/switch.c index 6ba664ccb..a5b1d79ce 100644 --- a/lib/fpga/switch.c +++ b/lib/fpga/ips/switch.c @@ -12,14 +12,16 @@ #include "log.h" #include "plugin.h" -#include "fpga/switch.h" #include "fpga/ip.h" +#include "fpga/card.h" +#include "fpga/ips/switch.h" -int switch_init(struct ip *c) +int switch_init(struct fpga_ip *c) { int ret; + + struct fpga_card *f = c->card; struct sw *sw = &c->sw; - struct fpga *f = c->card; XAxis_Switch *xsw = &sw->inst; @@ -29,7 +31,7 @@ int switch_init(struct ip *c) /* Setup AXI-stream switch */ XAxis_Switch_Config sw_cfg = { - .BaseAddress = (uintptr_t) c->card->map + c->baseaddr, + .BaseAddress = (uintptr_t) f->map + c->baseaddr, .MaxNumMI = sw->num_ports, .MaxNumSI = sw->num_ports }; @@ -42,11 +44,13 @@ int switch_init(struct ip *c) XAxisScr_RegUpdateDisable(xsw); XAxisScr_MiPortDisableAll(xsw); XAxisScr_RegUpdateEnable(xsw); + + switch_init_paths(c); return 0; } -int switch_init_paths(struct ip *c) +int switch_init_paths(struct fpga_ip *c) { int ret; struct sw *sw = &c->sw; @@ -57,7 +61,7 @@ int switch_init_paths(struct ip *c) XAxisScr_MiPortDisableAll(xsw); list_foreach(struct sw_path *p, &sw->paths) { - struct ip *mi, *si; + struct fpga_ip *mi, *si; mi = list_lookup(&c->card->ips, p->out); si = list_lookup(&c->card->ips, p->in); @@ -75,15 +79,18 @@ int switch_init_paths(struct ip *c) return 0; } -void switch_destroy(struct ip *c) +int switch_destroy(struct fpga_ip *c) { struct sw *sw = &c->sw; list_destroy(&sw->paths, NULL, true); + + return 0; } -int switch_parse(struct ip *c) +int switch_parse(struct fpga_ip *c) { + struct fpga_card *f = c->card; struct sw *sw = &c->sw; list_init(&sw->paths); @@ -93,7 +100,7 @@ int switch_parse(struct ip *c) if (!config_setting_lookup_int(c->cfg, "num_ports", &sw->num_ports)) cerror(c->cfg, "Switch IP '%s' requires 'num_ports' option", c->name); - cfg_sw = config_setting_get_member(c->card->cfg, "paths"); + cfg_sw = config_setting_get_member(f->cfg, "paths"); if (!cfg_sw) return 0; /* no switch config available */ @@ -133,7 +140,7 @@ int switch_parse(struct ip *c) return 0; } -int switch_connect(struct ip *c, struct ip *mi, struct ip *si) +int switch_connect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si) { struct sw *sw = &c->sw; XAxis_Switch *xsw = &sw->inst; @@ -169,7 +176,7 @@ int switch_connect(struct ip *c, struct ip *mi, struct ip *si) return 0; } -int switch_disconnect(struct ip *c, struct ip *mi, struct ip *si) +int switch_disconnect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si) { struct sw *sw = &c->sw; XAxis_Switch *xsw = &sw->inst; @@ -187,10 +194,11 @@ static struct plugin p = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "xilinx.com", "ip", "axis_interconnect", NULL }, - .init = switch_init, + .vlnv = { "xilinx.com", "ip", "axis_interconnect", NULL }, + .type = FPGA_IP_TYPE_MISC, + .init = switch_init, .destroy = switch_destroy, - .parse = switch_parse + .parse = switch_parse } }; diff --git a/lib/fpga/timer.c b/lib/fpga/ips/timer.c similarity index 82% rename from lib/fpga/timer.c rename to lib/fpga/ips/timer.c index 051eeb6b7..15de04544 100644 --- a/lib/fpga/timer.c +++ b/lib/fpga/ips/timer.c @@ -13,12 +13,13 @@ #include "plugin.h" #include "fpga/ip.h" -#include "fpga/timer.h" +#include "fpga/card.h" +#include "fpga/ips/timer.h" -int timer_init(struct ip *c) +int timer_init(struct fpga_ip *c) { + struct fpga_card *f = c->card; struct timer *tmr = &c->timer; - struct fpga *f = c->card; XTmrCtr *xtmr = &tmr->inst; XTmrCtr_Config xtmr_cfg = { @@ -37,8 +38,9 @@ static struct plugin p = { .description = "", .type = PLUGIN_TYPE_FPGA_IP, .ip = { - .vlnv = { "xilinx.com", "ip", "axi_timer", NULL }, - .init = timer_init + .vlnv = { "xilinx.com", "ip", "axi_timer", NULL }, + .type = FPGA_IP_TYPE_MISC, + .init = timer_init } }; diff --git a/lib/fpga/vlnv.c b/lib/fpga/vlnv.c new file mode 100644 index 000000000..e656fea43 --- /dev/null +++ b/lib/fpga/vlnv.c @@ -0,0 +1,45 @@ +/** Vendor, Library, Name, Version (VLNV) tag + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + */ + +#include +#include + +#include "fpga/vlnv.h" + +int fpga_vlnv_cmp(struct fpga_vlnv *a, struct fpga_vlnv *b) +{ + return ((!a->vendor || !b->vendor || !strcmp(a->vendor, b->vendor )) && + (!a->library || !b->library || !strcmp(a->library, b->library)) && + (!a->name || !b->name || !strcmp(a->name, b->name )) && + (!a->version || !b->version || !strcmp(a->version, b->version))) ? 0 : 1; +} + +int fpga_vlnv_parse(struct fpga_vlnv *c, const char *vlnv) +{ + char *tmp = strdup(vlnv); + + c->vendor = strdup(strtok(tmp, ":")); + c->library = strdup(strtok(NULL, ":")); + c->name = strdup(strtok(NULL, ":")); + c->version = strdup(strtok(NULL, ":")); + + free(tmp); + + return 0; +} + +int fpga_vlnv_destroy(struct fpga_vlnv *v) +{ + free(v->vendor); + free(v->library); + free(v->name); + free(v->version); + + return 0; +} diff --git a/lib/nodes/fpga.c b/lib/nodes/fpga.c index 0c71f3070..7e5487e3e 100644 --- a/lib/nodes/fpga.c +++ b/lib/nodes/fpga.c @@ -19,73 +19,38 @@ #include "timing.h" #include "plugin.h" -struct fpga fpga; -struct pci pci; -struct vfio_container vc; +#include "fpga/card.h" -int fpga_reset(struct fpga *f) -{ - int ret; - char state[4096]; - - /* Save current state of PCI configuration space */ - ret = pread(f->vd.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40); - if (ret != sizeof(state)) - return -1; - - uint32_t *rst_reg = (uint32_t *) (f->map + f->reset->baseaddr); - - debug(3, "FPGA: reset"); - rst_reg[0] = 1; - - usleep(100000); - - /* Restore previous state of PCI configuration space */ - ret = pwrite(f->vd.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40); - if (ret != sizeof(state)) - return -1; - - /* After reset the value should be zero again */ - if (rst_reg[0]) - return -2; - - return 0; -} +static struct list cards; +static struct pci pci; +static struct vfio_container vc; void fpga_dump(struct fpga *f) { + struct fpga_card *c = f->ip->card; + info("VILLASfpga card:"); { INDENT - info("Slot: %04x:%02x:%02x.%d", fpga.vd.pdev->slot.domain, fpga.vd.pdev->slot.bus, fpga.vd.pdev->slot.device, fpga.vd.pdev->slot.function); - info("Vendor ID: %04x", fpga.vd.pdev->id.vendor); - info("Device ID: %04x", fpga.vd.pdev->id.device); - info("Class ID: %04x", fpga.vd.pdev->id.class); + info("Slot: %04x:%02x:%02x.%d", c->vd.pdev->slot.domain, c->vd.pdev->slot.bus, c->vd.pdev->slot.device, c->vd.pdev->slot.function); + info("Vendor ID: %04x", c->vd.pdev->id.vendor); + info("Device ID: %04x", c->vd.pdev->id.device); + info("Class ID: %04x", c->vd.pdev->id.class); - info("BAR0 mapped at %p", fpga.map); + info("BAR0 mapped at %p", c->map); info("IP blocks:"); - list_foreach(struct ip *i, &f->ips) { INDENT - ip_dump(i); + list_foreach(struct fpga_ip *i, &c->ips) { INDENT + fpga_ip_dump(i); } } - vfio_dump(fpga.vd.group->container); + vfio_dump(c->vd.group->container); } -struct fpga * fpga_get() -{ - return &fpga; -} - -int fpga_parse_card(struct fpga *f, int argc, char * argv[], config_setting_t *cfg) +int fpga_parse_cards(config_setting_t *cfg) { int ret; - const char *slot, *id, *err; - config_setting_t *cfg_ips, *cfg_slot, *cfg_id, *cfg_fpgas; - - /* Default values */ - f->filter.id.vendor = FPGA_PCI_VID_XILINX; - f->filter.id.device = FPGA_PCI_PID_VFPGA; + config_setting_t *cfg_fpgas; cfg_fpgas = config_setting_get_member(cfg, "fpgas"); if (!cfg_fpgas) @@ -94,56 +59,16 @@ int fpga_parse_card(struct fpga *f, int argc, char * argv[], config_setting_t *c if (!config_setting_is_group(cfg_fpgas)) cerror(cfg_fpgas, "FPGA configuration section must be a group"); - if (config_setting_length(cfg_fpgas) != 1) - cerror(cfg_fpgas, "Currently, only a single FPGA is currently supported."); - - f->cfg = config_setting_get_elem(cfg_fpgas, 0); - - if (!config_setting_lookup_int(cfg, "affinity", &f->affinity)) - f->affinity = 0; - - config_setting_lookup_bool(f->cfg, "do_reset", &f->do_reset); - - cfg_slot = config_setting_get_member(f->cfg, "slot"); - if (cfg_slot) { - slot = config_setting_get_string(cfg_slot); - if (slot) { - ret = pci_dev_parse_slot(&f->filter, slot, &err); - if (ret) - cerror(cfg_slot, "Failed to parse PCI slot: %s", err); - } - else - cerror(cfg_slot, "PCI slot must be a string"); - } - - cfg_id = config_setting_get_member(f->cfg, "id"); - if (cfg_id) { - id = config_setting_get_string(cfg_id); - if (id) { - ret = pci_dev_parse_id(&f->filter, (char*) id, &err); - if (ret) - cerror(cfg_id, "Failed to parse PCI id: %s", err); - } - else - cerror(cfg_slot, "PCI ID must be a string"); - } - - cfg_ips = config_setting_get_member(f->cfg, "ips"); - if (!cfg_ips) - cerror(f->cfg, "FPGA configuration is missing ips section"); - - for (int i = 0; i < config_setting_length(cfg_ips); i++) { - config_setting_t *cfg_ip = config_setting_get_elem(cfg_ips, i); - - struct ip ip = { - .card = f - }; - - ret = ip_parse(&ip, cfg_ip); + for (int i = 0; i < config_setting_length(cfg_fpgas); i++) { + config_setting_t *cfg_fpga = config_setting_get_elem(cfg_fpgas, i); + + struct fpga_card *c = alloc(sizeof(struct fpga_card)); + + ret = fpga_card_parse(c, cfg_fpga); if (ret) - cerror(cfg_ip, "Failed to parse VILLASfpga IP core"); - - list_push(&f->ips, memdup(&ip, sizeof(ip))); + cerror(cfg_fpga, "Failed to parse FPGA card configuration"); + + list_push(&cards, c); } return 0; @@ -152,77 +77,19 @@ int fpga_parse_card(struct fpga *f, int argc, char * argv[], config_setting_t *c int fpga_init(int argc, char * argv[], config_setting_t *cfg) { int ret; - struct fpga *f; - struct pci_dev *pdev; - - /* For now we only support a single VILALSfpga card */ - f = fpga_get(); - list_init(&f->ips); - - pci_init(&pci); - pci_dev_init(&f->filter); - - /* Parse FPGA configuration */ - ret = fpga_parse_card(f, argc, argv, cfg); + + ret = pci_init(&pci); if (ret) - cerror(cfg, "Failed to parse VILLASfpga config"); - - /* Check FPGA configuration */ - f->reset = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_gpio", NULL); - if (!f->reset) - error("FPGA is missing a reset controller"); - - f->intc = ip_vlnv_lookup(&f->ips, "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL); - if (!f->intc) - error("FPGA is missing a interrupt controller"); - - f->sw = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axis_interconnect", NULL); - if (!f->sw) - warn("FPGA is missing an AXI4-Stream switch"); - - /* Search for FPGA card */ - pdev = pci_lookup_device(&pci, &f->filter); - if (!pdev) - error("Failed to find PCI device"); - - /* Get VFIO handles and details */ + cerror(cfg, "Failed to initialize PCI sub-system"); + ret = vfio_init(&vc); if (ret) - serror("Failed to initialize VFIO"); + cerror(cfg, "Failed to initiliaze VFIO sub-system"); - /* Attach PCIe card to VFIO container */ - ret = vfio_pci_attach(&f->vd, &vc, pdev); + /* Parse FPGA configuration */ + ret = fpga_parse_cards(cfg); if (ret) - error("Failed to attach VFIO device"); - - /* Map PCIe BAR */ - f->map = vfio_map_region(&f->vd, VFIO_PCI_BAR0_REGION_INDEX); - if (f->map == MAP_FAILED) - serror("Failed to mmap() BAR0"); - - /* Enable memory access and PCI bus mastering for DMA */ - ret = vfio_pci_enable(&f->vd); - if (ret) - serror("Failed to enable PCI device"); - - /* Reset system? */ - if (f->do_reset) { - /* Reset / detect PCI device */ - ret = vfio_pci_reset(&f->vd); - if (ret) - serror("Failed to reset PCI device"); - - ret = fpga_reset(f); - if (ret) - error("Failed to reset FGPA card"); - } - - /* Initialize IP cores */ - list_foreach(struct ip *c, &f->ips) { - ret = ip_init(c); - if (ret) - error("Failed to initalize IP core: %s (%u)", c->name, ret); - } + cerror(cfg, "Failed to parse VILLASfpga config"); return 0; } @@ -231,53 +98,78 @@ int fpga_deinit() { int ret; - list_destroy(&fpga.ips, (dtor_cb_t) ip_destroy, true); + list_destroy(&cards, (dtor_cb_t) fpga_card_destroy, true); pci_destroy(&pci); ret = vfio_destroy(&vc); if (ret) - error("Failed to deinitialize VFIO module"); + error("Failed to deinitialize VFIO sub-system"); + + ret = pci_destroy(&pci); + if (ret) + error("Failed to deinitialize PCI sub-system"); return 0; } int fpga_parse(struct node *n, config_setting_t *cfg) { - struct fpga_dm *d = n->_vd; + struct fpga *f = n->_vd; + struct fpga_card *card; + struct fpga_ip *ip; - /* There is currently only support for a single FPGA card */ - d->card = fpga_get(); + char *cpy, *card_name, *ip_name; + const char *dm; - if (!config_setting_lookup_string(cfg, "datamover", &d->ip_name)) + if (!config_setting_lookup_string(cfg, "datamover", &dm)) cerror(cfg, "Node '%s' is missing the 'datamover' setting", node_name(n)); - if (!config_setting_lookup_bool(cfg, "use_irqs", &d->use_irqs)) - d->use_irqs = false; + if (!config_setting_lookup_bool(cfg, "use_irqs", &f->use_irqs)) + f->use_irqs = false; + + cpy = strdup(dm); /* strtok can not operate on type const char * */ + + card_name = strtok(cpy, ":"); + ip_name = strtok(NULL, ":"); + + card = list_lookup(&cards, card_name); + if (!card) + cerror(cfg, "There is no FPGA card named '%s", card_name); + + ip = list_lookup(&card->ips, ip_name); + if (!ip) + cerror(cfg, "There is no datamover named '%s' on the FPGA card '%s'", ip_name, card_name); + if (!ip->_vt->type != FPGA_IP_TYPE_DATAMOVER) + cerror(cfg, "The IP '%s' on FPGA card '%s' is not a datamover", ip_name, card_name); + + free(cpy); + + f->ip = ip; return 0; } char * fpga_print(struct node *n) { - struct fpga_dm *d = n->_vd; - struct fpga *f = d->card; + struct fpga *f = n->_vd; + struct fpga_card *c = f->ip->card; - if (d->ip) + if (f->ip) return strf("dm=%s (%s:%s:%s:%s) baseaddr=%#jx port=%u slot=%02"PRIx8":%02"PRIx8".%"PRIx8" id=%04"PRIx16":%04"PRIx16, - d->ip->name, d->ip->vlnv.vendor, d->ip->vlnv.library, d->ip->vlnv.name, d->ip->vlnv.version, - d->ip->baseaddr, d->ip->port, - f->filter.slot.bus, f->filter.slot.device, f->filter.slot.function, - f->filter.id.vendor, f->filter.id.device); + f->ip->name, f->ip->vlnv.vendor, f->ip->vlnv.library, f->ip->vlnv.name, f->ip->vlnv.version, + f->ip->baseaddr, f->ip->port, + c->filter.slot.bus, c->filter.slot.device, c->filter.slot.function, + c->filter.id.vendor, c->filter.id.device); else - return strf("dm=%s", d->ip_name); + return strf("dm=%s", f->ip->name); } -int fpga_get_type(struct ip *c) +int fpga_get_type(struct fpga_ip *c) { - if (ip_vlnv_match(c, "xilinx.com", "ip", "axi_dma", NULL)) + if (!fpga_vlnv_cmp(&c->vlnv, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL })) return FPGA_DM_DMA; - else if (ip_vlnv_match(c, "xilinx.com", "ip", "axi_fifo_mm_s", NULL)) + else if (!fpga_vlnv_cmp(&c->vlnv, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_fifo_mm_s", NULL })) return FPGA_DM_FIFO; else return -1; @@ -287,36 +179,28 @@ int fpga_open(struct node *n) { int ret; - struct fpga_dm *d = n->_vd; - struct fpga *f = d->card; + struct fpga *f = n->_vd; + struct fpga_card *c = f->ip->card; - d->ip = list_lookup(&d->card->ips, d->ip_name); - if (!d->ip) - cerror(n->cfg, "Datamover '%s' is unknown. Please specify it in the fpga.ips section", d->ip_name); - - d->type = fpga_get_type(d->ip); - if (d->type < 0) - cerror(n->cfg, "IP '%s' is not a supported datamover", d->ip->name); - - switch_init_paths(f->sw); + fpga_card_init(c, &pci, &vc); int flags = 0; - if (!d->use_irqs) + if (!f->use_irqs) flags |= INTC_POLLING; - switch (d->type) { + switch (f->type) { case FPGA_DM_DMA: /* Map DMA accessible memory */ - ret = dma_alloc(d->ip, &d->dma, 0x1000, 0); + ret = dma_alloc(f->ip, &f->dma, 0x1000, 0); if (ret) return ret; - intc_enable(f->intc, (1 << (d->ip->irq )), flags); /* MM2S */ - intc_enable(f->intc, (1 << (d->ip->irq + 1)), flags); /* S2MM */ + intc_enable(c->intc, (1 << (f->ip->irq )), flags); /* MM2S */ + intc_enable(c->intc, (1 << (f->ip->irq + 1)), flags); /* S2MM */ break; case FPGA_DM_FIFO: - intc_enable(f->intc, (1 << d->ip->irq), flags); /* MM2S & S2MM */ + intc_enable(c->intc, (1 << f->ip->irq), flags); /* MM2S & S2MM */ break; } @@ -328,21 +212,21 @@ int fpga_close(struct node *n) { int ret; - struct fpga_dm *d = n->_vd; - struct fpga *f = d->card; + struct fpga *f = n->_vd; + struct fpga_card *c = f->ip->card; - switch (d->type) { + switch (f->type) { case FPGA_DM_DMA: - intc_disable(f->intc, d->ip->irq); /* MM2S */ - intc_disable(f->intc, d->ip->irq + 1); /* S2MM */ + intc_disable(c->intc, f->ip->irq); /* MM2S */ + intc_disable(c->intc, f->ip->irq + 1); /* S2MM */ - ret = dma_free(d->ip, &d->dma); + ret = dma_free(f->ip, &f->dma); if (ret) return ret; case FPGA_DM_FIFO: - if (d->use_irqs) - intc_disable(f->intc, d->ip->irq); /* MM2S & S2MM */ + if (f->use_irqs) + intc_disable(c->intc, f->ip->irq); /* MM2S & S2MM */ } return 0; @@ -352,7 +236,7 @@ int fpga_read(struct node *n, struct sample *smps[], unsigned cnt) { int ret; - struct fpga_dm *d = n->_vd; + struct fpga *f = n->_vd; struct sample *smp = smps[0]; size_t recvlen; @@ -364,22 +248,22 @@ int fpga_read(struct node *n, struct sample *smps[], unsigned cnt) smp->ts.origin = time_now(); /* Read data from RTDS */ - switch (d->type) { + switch (f->type) { case FPGA_DM_DMA: - ret = dma_read(d->ip, d->dma.base_phys + 0x800, len); + ret = dma_read(f->ip, f->dma.base_phys + 0x800, len); if (ret) return ret; - ret = dma_read_complete(d->ip, NULL, &recvlen); + ret = dma_read_complete(f->ip, NULL, &recvlen); if (ret) return ret; - memcpy(smp->data, d->dma.base_virt + 0x800, recvlen); + memcpy(smp->data, f->dma.base_virt + 0x800, recvlen); smp->length = recvlen / 4; return 1; case FPGA_DM_FIFO: - recvlen = fifo_read(d->ip, (char *) smp->data, len); + recvlen = fifo_read(f->ip, (char *) smp->data, len); smp->length = recvlen / 4; return 1; @@ -391,29 +275,22 @@ int fpga_read(struct node *n, struct sample *smps[], unsigned cnt) int fpga_write(struct node *n, struct sample *smps[], unsigned cnt) { int ret; - struct fpga_dm *d = n->_vd; + struct fpga *f = n->_vd; struct sample *smp = smps[0]; size_t sentlen; size_t len = smp->length * sizeof(smp->data[0]); - //intc_wait(f->intc, 5, 1); - - //if (n->received % 40000 == 0) { - // struct timespec now = time_now(); - // info("proc time = %f", time_delta(&smp->ts.origin, &now)); - //} - /* Send data to RTDS */ - switch (d->type) { + switch (f->type) { case FPGA_DM_DMA: - memcpy(d->dma.base_virt, smp->data, len); + memcpy(f->dma.base_virt, smp->data, len); - ret = dma_write(d->ip, d->dma.base_phys, len); + ret = dma_write(f->ip, f->dma.base_phys, len); if (ret) return ret; - ret = dma_write_complete(d->ip, NULL, &sentlen); + ret = dma_write_complete(f->ip, NULL, &sentlen); if (ret) return ret; @@ -421,7 +298,7 @@ int fpga_write(struct node *n, struct sample *smps[], unsigned cnt) return 1; case FPGA_DM_FIFO: - sentlen = fifo_write(d->ip, (char *) smp->data, len); + sentlen = fifo_write(f->ip, (char *) smp->data, len); return sentlen / sizeof(smp->data[0]); break; } @@ -434,7 +311,7 @@ static struct plugin p = { .description = "VILLASfpga PCIe card (libxil)", .type = PLUGIN_TYPE_NODE, .node = { - .size = sizeof(struct fpga_dm), + .size = sizeof(struct fpga), .vectorize = 1, .parse = fpga_parse, .print = fpga_print, diff --git a/src/fpga-bench-overruns.c b/src/fpga-bench-overruns.c index 73346b5e9..fd2f8a418 100644 --- a/src/fpga-bench-overruns.c +++ b/src/fpga-bench-overruns.c @@ -65,7 +65,7 @@ static int lapack_workload(int N, double *A) int fpga_benchmark_overruns(struct fpga *f) { - struct ip *rtds, *dm; + struct fpga_ip *rtds, *dm; dm = list_lookup(&f->ips, "dma_1"); rtds = list_lookup(&f->ips, "rtds_axis_0"); diff --git a/src/fpga-bench.c b/src/fpga-bench.c index 1de87f1f3..7dcb2a45f 100644 --- a/src/fpga-bench.c +++ b/src/fpga-bench.c @@ -7,9 +7,7 @@ **********************************************************************************/ #include -#include #include -#include #include #include @@ -87,7 +85,7 @@ int fpga_benchmark_jitter(struct fpga *f) { int ret; - struct ip *tmr; + struct fpga_ip *tmr; tmr = list_lookup(&f->ips, "timer_0"); if (!tmr || !f->intc) @@ -184,7 +182,7 @@ int fpga_benchmark_datamover(struct fpga *f) { int ret; - struct ip *dm; + struct fpga_ip *dm; struct dma_mem mem, src, dst; #if BENCH_DM == 1 diff --git a/src/fpga-tests.c b/src/fpga-tests.c index 0a44b569d..cade78278 100644 --- a/src/fpga-tests.c +++ b/src/fpga-tests.c @@ -7,11 +7,7 @@ *********************************************************************************/ #include -#include #include -#include -#include -#include #include @@ -96,12 +92,12 @@ int fpga_test_xsg(struct fpga *f) int ret; double factor, err = 0; - struct ip *xsg, *dma; + struct fpga_ip *xsg, *dma; struct model_param *p; struct dma_mem mem; - xsg = ip_vlnv_lookup(&f->ips, NULL, "sysgen", "xsg_multiply", NULL); - dma = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_dma", NULL); + xsg = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { NULL, "sysgen", "xsg_multiply", NULL }); + dma = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL }); /* Check if required IP is available on FPGA */ if (!dma || !xsg || !dma) @@ -160,10 +156,10 @@ int fpga_test_xsg(struct fpga *f) int fpga_test_hls_dft(struct fpga *f) { int ret; - struct ip *hls, *rtds; + struct fpga_ip *hls, *rtds; - rtds = ip_vlnv_lookup(&f->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); - hls = ip_vlnv_lookup(&f->ips, NULL, "hls", "hls_dft", NULL); + rtds = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); + hls = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { NULL, "hls", "hls_dft", NULL }); /* Check if required IP is available on FPGA */ if (!hls || !rtds) @@ -216,9 +212,9 @@ int fpga_test_fifo(struct fpga *f) int ret; ssize_t len; char src[255], dst[255]; - struct ip *fifo; + struct fpga_ip *fifo; - fifo = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_fifo_mm_s", NULL); + fifo = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }); if (!fifo) return -1; @@ -261,8 +257,8 @@ int fpga_test_dma(struct fpga *f) int ret = -1; struct dma_mem mem, src, dst; - list_foreach(struct ip *dma, &f->ips) { INDENT - if (!ip_vlnv_match(dma, "xilinx.com", "ip", "axi_dma", NULL)) + list_foreach(struct fpga_ip *dma, &f->ips) { INDENT + if (!fpga_vlnv_match(dma, "xilinx.com", "ip", "axi_dma", NULL)) continue; /* skip non DMA IP cores */ /* Simple DMA can only transfer up to 4 kb due to @@ -321,9 +317,9 @@ int fpga_test_dma(struct fpga *f) int fpga_test_timer(struct fpga *f) { int ret; - struct ip *tmr; + struct fpga_ip *tmr; - tmr = ip_vlnv_lookup(&f->ips, "xilinx.com", "ip", "axi_timer", NULL); + tmr = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_timer", NULL }); if (!tmr) return -1; @@ -355,12 +351,12 @@ int fpga_test_timer(struct fpga *f) int fpga_test_rtds_rtt(struct fpga *f) { int ret; - struct ip *dma, *rtds; + struct fpga_ip *dma, *rtds; struct dma_mem buf; size_t recvlen; /* Get IP cores */ - rtds = ip_vlnv_lookup(&f->ips, "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL); + rtds = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); dma = list_lookup(&f->ips, "dma_1"); /* Check if required IP is available on FPGA */ From 73c91ad5493543fdb729121743f94c769a29cc26 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:45:05 -0500 Subject: [PATCH 084/211] refactored more dtor_cb_t return types --- include/villas/kernel/if.h | 2 +- include/villas/kernel/pci.h | 6 +----- include/villas/kernel/vfio.h | 4 ++-- lib/kernel/if.c | 4 +++- lib/kernel/pci.c | 12 ++---------- lib/kernel/vfio.c | 8 ++++++-- lib/plugin.c | 2 ++ 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h index 8317270d7..5ef782503 100644 --- a/include/villas/kernel/if.h +++ b/include/villas/kernel/if.h @@ -50,7 +50,7 @@ struct interface * if_create(struct rtnl_link *link); * * @param i A pointer to the interface structure. */ -void if_destroy(struct interface *i); +int if_destroy(struct interface *i); /** Start interface. * diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h index ae4e6417a..07c247d60 100644 --- a/include/villas/kernel/pci.h +++ b/include/villas/kernel/pci.h @@ -43,11 +43,7 @@ struct pci { int pci_init(struct pci *p); /** Destroy handle. */ -void pci_destroy(struct pci *p); - -int pci_dev_init(struct pci_dev *d); - -void pci_dev_destroy(struct pci_dev *d); +int pci_destroy(struct pci *p); int pci_dev_parse_slot(struct pci_dev *f, const char *str, const char **error); diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 6c7c2868b..68c3c559e 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -88,10 +88,10 @@ int vfio_dev_reset(struct vfio_dev *d); int vfio_destroy(struct vfio_container *c); /** Release memory of group */ -void vfio_group_destroy(struct vfio_group *g); +int vfio_group_destroy(struct vfio_group *g); /** Release memory of device */ -void vfio_dev_destroy(struct vfio_dev *g); +int vfio_dev_destroy(struct vfio_dev *g); /** Print a dump of all attached groups and their devices including regions and IRQs */ void vfio_dump(struct vfio_container *c); diff --git a/lib/kernel/if.c b/lib/kernel/if.c index 60c0af1ff..3008d5752 100644 --- a/lib/kernel/if.c +++ b/lib/kernel/if.c @@ -41,7 +41,7 @@ struct interface * if_create(struct rtnl_link *link) return i; } -void if_destroy(struct interface *i) +int if_destroy(struct interface *i) { /* List members are freed by the nodes they belong to. */ list_destroy(&i->sockets, NULL, false); @@ -49,6 +49,8 @@ void if_destroy(struct interface *i) rtnl_qdisc_put(i->tc_qdisc); free(i); + + return 0; } int if_start(struct interface *i, int affinity) diff --git a/lib/kernel/pci.c b/lib/kernel/pci.c index bdd388f44..a40c5158b 100644 --- a/lib/kernel/pci.c +++ b/lib/kernel/pci.c @@ -65,21 +65,13 @@ int pci_init(struct pci *p) return 0; } -void pci_destroy(struct pci *p) +int pci_destroy(struct pci *p) { list_destroy(&p->devices, NULL, true); -} - -int pci_dev_init(struct pci_dev *d) -{ + return 0; } -void pci_dev_destroy(struct pci_dev *d) -{ - -} - int pci_dev_parse_slot(struct pci_dev *f, const char *s, const char **error) { char *str = strdup(s); diff --git a/lib/kernel/vfio.c b/lib/kernel/vfio.c index d5fb7f9a7..dcf2916fc 100644 --- a/lib/kernel/vfio.c +++ b/lib/kernel/vfio.c @@ -87,7 +87,7 @@ int vfio_destroy(struct vfio_container *v) return 0; } -void vfio_group_destroy(struct vfio_group *g) +int vfio_group_destroy(struct vfio_group *g) { int ret; @@ -104,9 +104,11 @@ void vfio_group_destroy(struct vfio_group *g) return; debug(5, "VFIO: closed group: group=%u, fd=%d", g->index, g->fd); + + return 0; } -void vfio_dev_destroy(struct vfio_dev *d) +int vfio_dev_destroy(struct vfio_dev *d) { int ret; @@ -121,6 +123,8 @@ void vfio_dev_destroy(struct vfio_dev *d) free(d->mappings); free(d->name); + + return 0; } /* Constructors */ diff --git a/lib/plugin.c b/lib/plugin.c index 6b57147b9..d32ae13ab 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -50,6 +50,8 @@ int plugin_destroy(struct plugin *p) free(p->name); free(p->path); + + return 0; } int plugin_parse(struct plugin *p, config_setting_t *lcs) From 309ec9f6a68ac6440dc488f8774cbb2df4465de6 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:47:15 -0500 Subject: [PATCH 085/211] refactored more #pragma once --- include/villas/hooks.h | 3 +-- include/villas/queue.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index e4e6dd68d..e26d4e8e0 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -18,8 +18,7 @@ * @{ *********************************************************************************/ -#ifndef _HOOKS_H_ -#define _HOOKS_H_ +#pragma once #include #include diff --git a/include/villas/queue.h b/include/villas/queue.h index 654ee4a49..3b42989be 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -31,6 +31,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#pragma once + #include #include From 7e411ed5ab4c94c3449e75500af968a20cac8e58 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:49:42 -0500 Subject: [PATCH 086/211] refactored more struct cfg stuff --- include/villas/hooks.h | 6 ++++-- include/villas/node.h | 1 - include/villas/utils.h | 2 +- lib/hooks.c | 12 ++++-------- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index e26d4e8e0..4dee690a8 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -27,12 +27,14 @@ #include "list.h" /* The configuration of hook parameters is done in "config.h" */ +#include "cfg.h" + /* Forward declarations */ struct path; struct hook; struct sample; -struct settings; +struct cfg; /** This is a list of hooks which can be used in the configuration file. */ extern struct list hooks; @@ -99,7 +101,7 @@ struct hook { }; /** Save references to global nodes, paths and settings */ -void hook_init(struct list *nodes, struct list *paths, struct settings *set); +void hook_init(struct cfg *cfg); /** Sort hook list according to the their priority. See hook::priority. */ int hooks_sort_priority(const void *a, const void *b); diff --git a/include/villas/node.h b/include/villas/node.h index 19111cec4..639ef3c35 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -23,7 +23,6 @@ extern struct list node_types; /**< Vtable for virtual node sub types */ /* Forward declarations */ -struct config_setting_t cfg; struct node_type; /** The data structure for a node. diff --git a/include/villas/utils.h b/include/villas/utils.h index ee5b5c43c..6f9f9b357 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -99,7 +99,7 @@ #define BIT(nr) (1UL << (nr)) /* Forward declarations */ -struct settings; +struct cfg; struct timespec; /** Print copyright message to screen. */ diff --git a/lib/hooks.c b/lib/hooks.c index 2e88e2813..7f642f520 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -16,19 +16,15 @@ #include "path.h" #include "utils.h" #include "node.h" +#include "cfg.h" struct list hooks; -/* Those references can be used inside the hook callbacks after initializing them with hook_init() */ -struct list *hook_nodes = NULL; -struct list *hook_paths = NULL; -struct settings *hook_settings = NULL; +struct cfg *cfg = NULL; -void hook_init(struct list *nodes, struct list *paths, struct settings *set) +void hook_init(struct cfg *c) { - hook_nodes = nodes; - hook_paths = paths; - hook_settings = set; + cfg = c; } int hooks_sort_priority(const void *a, const void *b) { From f03fe00bff673e586c5fc02651805372ffbd9acd Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:51:43 -0500 Subject: [PATCH 087/211] refactor more code to new plugin system --- include/villas/hooks.h | 14 ++++++++++++-- include/villas/plugin.h | 20 ++++++++++++++------ lib/nodes/cbuilder.c | 4 +--- lib/nodes/websocket.c | 23 ++++++++++++----------- lib/plugin.c | 17 +++++++---------- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/include/villas/hooks.h b/include/villas/hooks.h index 4dee690a8..dd9b70bfb 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -25,10 +25,20 @@ #include "queue.h" #include "list.h" - -/* The configuration of hook parameters is done in "config.h" */ #include "cfg.h" +#define REGISTER_HOOK(nam, desc, prio, hist, fnc, typ) \ +__attribute__((constructor)) void __register_ ## fnc () { \ + static struct hook h = { \ + .name = nam, \ + .description = desc, \ + .priority = prio, \ + .history = hist, \ + .type = typ, \ + .cb = fnc \ + }; \ + list_push(&hooks, &h); \ +} /* Forward declarations */ struct path; diff --git a/include/villas/plugin.h b/include/villas/plugin.h index c67fe5b51..5085ad6bd 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -11,8 +11,11 @@ #include "hooks.h" #include "api.h" + #include "fpga/ip.h" +#include "nodes/cbuilder.h" + #define REGISTER_PLUGIN(p) \ __attribute__((constructor)) static void UNIQUE(__ctor)() { \ list_push(&plugins, p); \ @@ -51,18 +54,23 @@ struct plugin { int (*unload)(struct plugin *p); union { - struct api_ressource api; - struct hook hook; - struct node_type node; + struct api_ressource api; + struct node_type node; + struct fpga_ip_type ip; + struct hook hook; + struct cbuilder_model cb; }; }; -struct plugin * plugin_lookup(char *name, enum plugin_types type); - int plugin_init(struct plugin *p, char *name, char *path); +int plugin_destroy(struct plugin *p); + +int plugin_parse(struct plugin *p, config_setting_t *cfg); + int plugin_load(struct plugin *p); int plugin_unload(struct plugin *p); -int plugin_destroy(struct plugin *p); +/** Find registered and loaded plugin with given name and type. */ +struct plugin * plugin_lookup(enum plugin_types type, const char *name); \ No newline at end of file diff --git a/lib/nodes/cbuilder.c b/lib/nodes/cbuilder.c index 8296b697a..1d10af991 100644 --- a/lib/nodes/cbuilder.c +++ b/lib/nodes/cbuilder.c @@ -12,8 +12,6 @@ #include "nodes/cbuilder.h" -struct list cbmodels; /**< Table of existing CBuilder models */ - int cbuilder_parse(struct node *n, config_setting_t *cfg) { struct cbuilder *cb = n->_vd; @@ -27,7 +25,7 @@ int cbuilder_parse(struct node *n, config_setting_t *cfg) if (!config_setting_lookup_string(cfg, "model", &model)) cerror(cfg, "CBuilder model requires 'model' setting"); - cb->model = list_lookup(&cbmodels, model); + cb->model = (struct cbuilder_model *) plugin_lookup(PLUGIN_TYPE_MODEL_CBUILDER, model); if (!cb->model) cerror(cfg, "Unknown model '%s'", model); diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index d7b51733c..4550d21d6 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -546,18 +546,19 @@ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt) return cnt; } -static struct node_type vt = { +static struct plugin p = { .name = "websocket", .description = "Send and receive samples of a WebSocket connection (libwebsockets)", - .vectorize = 0, /* unlimited */ - .size = sizeof(struct websocket), - .open = websocket_open, - .close = websocket_close, - .destroy = websocket_destroy, - .read = websocket_read, - .write = websocket_write, - .init = websocket_init, - .deinit = websocket_deinit + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 0, /* unlimited */ + .size = sizeof(struct websocket), + .open = websocket_open, + .close = websocket_close, + .destroy = websocket_destroy, + .read = websocket_read, + .write = websocket_write, + } }; -REGISTER_NODE_TYPE(&vt) \ No newline at end of file +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/plugin.c b/lib/plugin.c index d32ae13ab..41bd9e12a 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -54,7 +54,7 @@ int plugin_destroy(struct plugin *p) return 0; } -int plugin_parse(struct plugin *p, config_setting_t *lcs) +int plugin_parse(struct plugin *p, config_setting_t *cfg) { const char *path; @@ -62,23 +62,20 @@ int plugin_parse(struct plugin *p, config_setting_t *lcs) if (!path) cerror(cfg, "Setting 'plugin' must be a string."); - p-> + handle = dlopen(path, RTLD_NOW); + if (!handle) + error("Failed to load plugin %s", dlerror()); - handle = dlopen(path, RTLD_NOW); - if (!handle) - error("Failed to load plugin %s", dlerror()); - - list_push_back(&cfg->plugins, handle); - } + list_push_back(&cfg->plugins, handle); return 0; } -struct plugin * plugin_lookup(char *name, enum plugin_types type) +struct plugin * plugin_lookup(enum plugin_types type, const char *name) { list_foreach(struct plugin *l, &plugins) { if (l->type == type && strcmp(l->name, name) == 0) - return l + return l; } return NULL; From f92537172e34d9eeeaf27b2f87cd927a5d1b2547 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:57:29 -0500 Subject: [PATCH 088/211] separated websocket node-type into web, api modules --- include/villas/api.h | 106 ++++++++++++++++ include/villas/web.h | 42 +++++++ lib/Makefile.inc | 10 +- lib/api.c | 252 ++++++++++++++++++++++++++++++++++++++ lib/apis/Makefile.inc | 1 + lib/apis/config.c | 30 +++++ lib/apis/nodes.c | 48 ++++++++ lib/apis/reload.c | 23 ++++ lib/nodes/websocket.c | 272 +----------------------------------------- lib/web.c | 184 ++++++++++++++++++++++++++++ 10 files changed, 692 insertions(+), 276 deletions(-) create mode 100644 include/villas/api.h create mode 100644 include/villas/web.h create mode 100644 lib/api.c create mode 100644 lib/apis/Makefile.inc create mode 100644 lib/apis/config.c create mode 100644 lib/apis/nodes.c create mode 100644 lib/apis/reload.c create mode 100644 lib/web.c diff --git a/include/villas/api.h b/include/villas/api.h new file mode 100644 index 000000000..f75bc3426 --- /dev/null +++ b/include/villas/api.h @@ -0,0 +1,106 @@ +/** REST-API-releated functions. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#pragma once + +#include "list.h" + +#include + +/* Forward declarations */ +enum lws_callback_reasons; +struct lws; +struct cfg; + +struct api; +struct api_ressource; +struct api_buffer; +struct api_session; + +extern struct list apis; + +/** Callback type of command function + * + * @param[inout] c Command handle + * @param[in] args JSON command arguments. + * @param[out] resp JSON command response. + * @param[in] i Execution context. + */ +typedef int (*api_cb_t)(struct api_ressource *c, json_t *args, json_t **resp, struct api_session *s); + +enum api_version { + API_VERSION_UNKOWN = 0, + API_VERSION_1 = 1 +}; + +enum api_mode { + API_MODE_WS, /**< This API session was established over a WebSocket connection. */ + API_MODE_HTTP /**< This API session was established via a HTTP REST request. */ +}; + +struct api { + struct list sessions; /**< List of currently active connections */ + + struct cfg *cfg; +}; + +struct api_buffer { + char *buf; /**< A pointer to the buffer. Usually resized via realloc() */ + size_t size; /**< The allocated size of the buffer. */ + size_t len; /**< The used length of the buffer. */ + size_t sent; /**< Pointer to api_buffer::buf to indicate how much has been sent. */ +}; + +/** A connection via HTTP REST or WebSockets to issue API actions. */ +struct api_session { + enum api_mode mode; + enum api_version version; + + int runs; + + struct { + struct api_buffer body; /**< HTTP body / WS payload */ + } request; + + struct { + struct api_buffer body; /**< HTTP body / WS payload */ + struct api_buffer headers; /**< HTTP headers */ + } response; + + struct api *api; +}; + +/** Command descriptor + * + * Every command is described by a descriptor. + */ +struct api_ressource { + char *name; + char *description; + api_cb_t cb; +}; + +/** Initalize the API. + * + * Save references to list of paths / nodes for command execution. + */ +int api_init(struct api *a, struct cfg *cfg); + +int api_destroy(struct api *a); + +int api_deinit(struct api *a); + +int api_session_init(struct api_session *s, enum api_mode m); + +int api_session_destroy(struct api_session *s); + +int api_session_run_command(struct api_session *s, json_t *req, json_t **resp); + +/** Libwebsockets callback for "api" endpoint */ +int api_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); \ No newline at end of file diff --git a/include/villas/web.h b/include/villas/web.h new file mode 100644 index 000000000..81826b25b --- /dev/null +++ b/include/villas/web.h @@ -0,0 +1,42 @@ +/** LWS-releated functions. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#pragma once + +/* Forward declarations */ +struct api; + +struct web { + struct api *api; + + struct lws_context *context; /**< The libwebsockets server context. */ + struct lws_vhost *vhost; /**< The libwebsockets vhost. */ + + int port; /**< Port of the build in HTTP / WebSocket server. */ + const char *htdocs; /**< The root directory for files served via HTTP. */ + const char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */ + const char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */ +}; + +/** Initialize the web interface. + * + * The web interface is based on the libwebsockets library. + */ +int web_init(struct web *w, struct api *a); + +int web_destroy(struct web *w); + +/** Parse HTTPd and WebSocket related options */ +int web_parse(struct web *w, config_setting_t *lcs); + +/** De-initializes the web interface. */ +int web_deinit(struct web *w); + +/** libwebsockets service routine. Call periodically */ +int web_service(struct web *w); \ No newline at end of file diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 728653992..70b415678 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -6,8 +6,8 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ $(addprefix lib/, sample.c path.c node.c hooks.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ - queue.c memory.c advio.c \ - ) \ + queue.c memory.c advio.c web.c api.c \ + ) LIB_CFLAGS = $(CFLAGS) -fPIC LIB_LDFLAGS = -shared @@ -47,12 +47,12 @@ endif endif # Enable WebSocket support -ifndef WITHOUT_WEBSOCKETS +#ifndef WITHOUT_WEBSOCKETS ifeq ($(shell pkg-config libwebsockets jansson; echo $$?),0) - LIB_SRCS += lib/nodes/websocket.c +# LIB_SRCS += lib/nodes/websocket.c LIB_PKGS += libwebsockets jansson endif -endif +#endif # Enable OPAL-RT Asynchronous Process support (will result in 32bit binary!!!) ifdef WITH_OPAL diff --git a/lib/api.c b/lib/api.c new file mode 100644 index 000000000..dc9efca0d --- /dev/null +++ b/lib/api.c @@ -0,0 +1,252 @@ +/** REST-API-releated functions. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include + +#include "api.h" +#include "log.h" +#include "config.h" + +static int parse_request(struct api_buffer *b, json_t **req) +{ + json_error_t e; + + if (b->len <= 0) + return -1; + + *req = json_loadb(b->buf, b->len, JSON_DISABLE_EOF_CHECK, &e); + if (!*req) + return -1; + + if (e.position < b->len) { + void *dst = (void *) b->buf; + void *src = (void *) (b->buf + e.position); + + memmove(dst, src, b->len - e.position); + + b->len -= e.position; + + return 1; + } + + return 0; +} + +#if JANSSON_VERSION_HEX < 0x020A00 +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) +{ + char *str = json_dumps(json, flags); + size_t len = strlen(str) - 1; // not \0 terminated + + if (!buffer || len > size) + return len; + else + memcpy(buffer, str, len); + + return len; +} +#endif + +static int unparse_response(struct api_buffer *b, json_t *res) +{ + size_t len; + + retry: len = json_dumpb(res, b->buf + b->len, b->size - b->len, 0); + if (len > b->size - b->len) { + b->buf = realloc(b->buf, b->len + len); + goto retry; + } + + return 0; +} + +int api_session_run_command(struct api_session *s, json_t *req, json_t **resp) +{ + int ret; + const char *rstr; + struct api_ressource *res; + + json_t *args; + + ret = json_unpack(req, "{ s: s, s: o }", + "command", &rstr, + "arguments", &args); + if (ret) + *resp = json_pack("{ s: s, s: d }", + "error", "invalid request", + "code", -1); + + res = list_lookup(&apis, rstr); + if (!res) + *resp = json_pack("{ s: s, s: d, s: s }", + "error", "command not found", + "code", -2, + "command", rstr); + + ret = res->cb(res, args, resp, s); + if (ret) + *resp = json_pack("{ s: s, s: d }", + "error", "command failed", + "code", ret); + + return 0; +} + +int api_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +{ + int ret; + + struct api_session *s = (struct api_session *) user; + + switch (reason) { + case LWS_CALLBACK_ESTABLISHED: + api_session_init(s, API_MODE_WS); + break; + + case LWS_CALLBACK_HTTP: + if (len < 1) { + lws_return_http_status(wsi, HTTP_STATUS_BAD_REQUEST, NULL); + return -1; + } + + char *uri = (char *) in; + + /* Parse request URI */ + ret = sscanf(uri, "/api/v%d", (int *) &s->version); + if (ret != 1) + return -1; + + debug(LOG_API, "New REST API session initiated: version = %d", s->version); + + api_session_init(s, API_MODE_HTTP); + + /* Prepare HTTP response header */ + s->response.headers.buf = alloc(512); + + unsigned char *p = (unsigned char *) s->response.headers.buf; + unsigned char *e = (unsigned char *) s->response.headers.buf + 512; + + ret = lws_add_http_header_status(wsi, 200, &p, e); + if (ret) + return 1; + ret = lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *) USER_AGENT, strlen(USER_AGENT), &p, e); + if (ret) + return 1; + ret = lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *) "application/json", strlen("application/json"), &p, e); + if (ret) + return 1; + //ret = lws_add_http_header_content_length(wsi, file_len, &p, e); + //if (ret) + // return 1; + ret = lws_finalize_http_header(wsi, &p, e); + if (ret) + return 1; + + *p = '\0'; + + s->response.headers.len = p - (unsigned char *) s->response.headers.buf + 1; + s->response.headers.sent = 0; + + /* book us a LWS_CALLBACK_HTTP_WRITEABLE callback */ + lws_callback_on_writable(wsi); + + break; + + case LWS_CALLBACK_CLIENT_RECEIVE: + case LWS_CALLBACK_RECEIVE: + case LWS_CALLBACK_HTTP_BODY: { + char *newbuf; + + newbuf = realloc(s->request.body.buf, s->request.body.len + len); + + s->request.body.buf = memcpy(newbuf + s->request.body.len, in, len); + s->request.body.len += len; + + json_t *req, *resp; + while (parse_request(&s->request.body, &req) == 1) { + + api_session_run_command(s, req, &resp); + + unparse_response(&s->response.body, resp); + } + + break; + } + + case LWS_CALLBACK_HTTP_BODY_COMPLETION: + return -1; /* close connection */ + + case LWS_CALLBACK_SERVER_WRITEABLE: + case LWS_CALLBACK_HTTP_WRITEABLE: { + enum lws_write_protocol prot; + struct api_buffer *protbuf; + + if (s->mode == API_MODE_HTTP && s->response.headers.sent < s->response.headers.len) { + prot = LWS_WRITE_HTTP_HEADERS; + protbuf = &s->response.headers; + } + else if (s->response.body.sent < s->response.body.len) { + prot = LWS_WRITE_HTTP; + protbuf = &s->response.body; + } + else + break; + + int sent; + + void *buf = (void *) (protbuf->buf + protbuf->sent); + size_t len = protbuf->len - protbuf->sent; + + sent = lws_write(wsi, buf, len, prot); + if (sent > 0) + protbuf->sent += sent; + else + return -1; + + break; + } + + default: + return 0; + } + + return 0; + +} + +int api_init(struct api *a, struct cfg *cfg) +{ + list_init(&a->sessions); + + a->cfg = cfg; + + return 0; +} + +int api_deinit(struct api *a) +{ + list_destroy(&a->sessions, (dtor_cb_t) api_session_destroy, false); + + return 0; +} + +int api_session_init(struct api_session *s, enum api_mode m) +{ + s->mode = m; + + s->request.body = + s->response.body = + s->response.headers = (struct api_buffer) { 0 }; + + return 0; +} + +int api_session_destroy(struct api_session *s) +{ + return 0; +} diff --git a/lib/apis/Makefile.inc b/lib/apis/Makefile.inc new file mode 100644 index 000000000..f249c5bbf --- /dev/null +++ b/lib/apis/Makefile.inc @@ -0,0 +1 @@ +LIB_SRCS += $(wildcard lib/cmds/*.c) \ No newline at end of file diff --git a/lib/apis/config.c b/lib/apis/config.c new file mode 100644 index 000000000..a0db95c8d --- /dev/null +++ b/lib/apis/config.c @@ -0,0 +1,30 @@ +/** The "config" command + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include "api.h" +#include "utils.h" +#include "plugin.h" + +static int api_config(struct api_ressource *h, json_t *args, json_t **resp, struct api_info *i) +{ + if (!i->settings.config) + return -1; + + *resp = config_to_json(config_setting_root(i->settings.config)); + + return 0; +} + +static struct plugin p = { + .name = "config", + .description = "retrieve current VILLASnode configuration", + .type = PLUGIN_TYPE_API, + .api.cb = api_config +}; + +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/apis/nodes.c b/lib/apis/nodes.c new file mode 100644 index 000000000..106185586 --- /dev/null +++ b/lib/apis/nodes.c @@ -0,0 +1,48 @@ +/** The "nodes" command + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include + +#include "api.h" +#include "node.h" +#include "utils.h" + +extern struct list nodes; + +static int api_nodes(struct api_ressource *r, json_t *args, json_t **resp, struct api_info *i) +{ + json_t *json_nodes = json_array(); + + list_foreach(struct node *n, i->nodes) { + json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i }", + "name", node_name_short(n), + "state", n->state, + "vectorize", n->vectorize, + "affinity", n->affinity + ); + + /* Add all additional fields of node here. + * This can be used for metadata */ + json_object_update(json_node, config_to_json(n->cfg)); + + json_array_append_new(json_nodes, json_node); + } + + *resp = json_nodes; + + return 0; +} + +static struct plugin p = { + .name = "nodes", + .description = "retrieve list of all known nodes", + .type = PLUGIN_TYPE_API, + .api.cb = api_nodes +}; + +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/apis/reload.c b/lib/apis/reload.c new file mode 100644 index 000000000..796ba724a --- /dev/null +++ b/lib/apis/reload.c @@ -0,0 +1,23 @@ +/** The "reload" command + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include "api.h" + +static int api_reload(struct api_ressource *h, json_t *args, json_t **resp, struct api_info *i) +{ + return -1; +} + +static struct plugin p = { + .name = "reload", + .description = "restart VILLASnode with new configuration", + .type = PLUGIN_TYPE_API, + .api.cb = api_reload +}; + +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index 4550d21d6..ed3eb37ea 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -22,225 +22,10 @@ #include "cfg.h" #include "config.h" -/* Private static storage */ -static config_setting_t *cfg_root; /**< Root config */ -static pthread_t thread; /**< All nodes are served by a single websocket server. This server is running in a dedicated thread. */ -static struct lws_context *context; /**< The libwebsockets server context. */ - -static int port; /**< Port of the build in HTTP / WebSocket server */ - -static const char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS */ -static const char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS */ -static const char *htdocs; /**< Path to the directory which should be served by build in HTTP server */ - /* Forward declarations */ static struct node_type vt; -static int protocol_cb_http(struct lws *, enum lws_callback_reasons, void *, void *, size_t); -static int protocol_cb_live(struct lws *, enum lws_callback_reasons, void *, void *, size_t); -static struct lws_protocols protocols[] = { - { - "http-only", - protocol_cb_http, - 0, - 0 - }, - { - "live", - protocol_cb_live, - sizeof(struct websocket_connection), - 0 - }, - { 0 /* terminator */ } -}; - -#if 0 -static const struct lws_extension exts[] = { - { - "permessage-deflate", - lws_extension_callback_pm_deflate, - "permessage-deflate" - }, - { - "deflate-frame", - lws_extension_callback_pm_deflate, - "deflate_frame" - }, - { NULL, NULL, NULL /* terminator */ } -}; -#endif - -static void logger(int level, const char *msg) { - int len = strlen(msg); - if (strchr(msg, '\n')) - len -= 1; - - /* Decrease severity for some errors. */ - if (strstr(msg, "Unable to open") == msg) - level = LLL_WARN; - - switch (level) { - case LLL_ERR: error("LWS: %.*s", len, msg); break; - case LLL_WARN: warn("LWS: %.*s", len, msg); break; - case LLL_INFO: info("LWS: %.*s", len, msg); break; - default: debug(DBG_WEBSOCKET | 1, "LWS: %.*s", len, msg); break; - } -} - -static void * server_thread(void *ctx) -{ - debug(DBG_WEBSOCKET | 3, "WebSocket: Started server thread"); - - while (lws_service(context, 10) >= 0); - - debug(DBG_WEBSOCKET | 3, "WebSocket: shutdown voluntarily"); - - return NULL; -} - -/* Choose mime type based on the file extension */ -static char * get_mimetype(const char *resource_path) -{ - char *extension = strrchr(resource_path, '.'); - - if (extension == NULL) - return "text/plain"; - else if (!strcmp(extension, ".png")) - return "image/png"; - else if (!strcmp(extension, ".svg")) - return "image/svg+xml"; - else if (!strcmp(extension, ".jpg")) - return "image/jpg"; - else if (!strcmp(extension, ".gif")) - return "image/gif"; - else if (!strcmp(extension, ".html")) - return "text/html"; - else if (!strcmp(extension, ".css")) - return "text/css"; - else if (!strcmp(extension, ".js")) - return "application/javascript"; - else - return "text/plain"; -} - -int protocol_cb_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) -{ - switch (reason) { - case LWS_CALLBACK_HTTP: - if (!htdocs) { - lws_return_http_status(wsi, HTTP_STATUS_SERVICE_UNAVAILABLE, NULL); - goto try_to_reuse; - } - - if (len < 1) { - lws_return_http_status(wsi, HTTP_STATUS_BAD_REQUEST, NULL); - goto try_to_reuse; - } - - char *requested_uri = (char *) in; - - debug(DBG_WEBSOCKET | 3, "LWS: New HTTP request: %s", requested_uri); - - /* Handle default path */ - if (!strcmp(requested_uri, "/")) { - char *response = "HTTP/1.1 302 Found\r\n" - "Content-Length: 0\r\n" - "Location: /index.html\r\n" - "\r\n"; - - lws_write(wsi, (void *) response, strlen(response), LWS_WRITE_HTTP); - - goto try_to_reuse; - } -#ifdef WITH_JANSSON - /* Return list of websocket nodes */ - else if (!strcmp(requested_uri, "/nodes.json")) { - json_t *json_body = json_array(); - - list_foreach(struct node *n, &vt.instances) { - struct websocket *w = n->_vd; - - json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i }", - "name", node_name_short(n), - "connections", list_length(&w->connections), - "state", n->state, - "vectorize", n->vectorize, - "affinity", n->affinity - ); - - /* Add all additional fields of node here. - * This can be used for metadata */ - json_object_update(json_node, config_to_json(n->cfg)); - - json_array_append_new(json_body, json_node); - } - - char *body = json_dumps(json_body, JSON_INDENT(4)); - - char *header = "HTTP/1.1 200 OK\r\n" - "Connection: close\r\n" - "Content-Type: application/json\r\n" - "\r\n"; - - lws_write(wsi, (void *) header, strlen(header), LWS_WRITE_HTTP); - lws_write(wsi, (void *) body, strlen(body), LWS_WRITE_HTTP); - - free(body); - json_decref(json_body); - - return -1; - } - else if (!strcmp(requested_uri, "/config.json")) { - char *body = json_dumps(config_to_json(cfg_root), JSON_INDENT(4)); - - char *header = "HTTP/1.1 200 OK\r\n" - "Connection: close\r\n" - "Content-Type: application/json\r\n" - "\r\n"; - - lws_write(wsi, (void *) header, strlen(header), LWS_WRITE_HTTP); - lws_write(wsi, (void *) body, strlen(body), LWS_WRITE_HTTP); - - free(body); - - return -1; - } -#endif - else { - char path[4069]; - snprintf(path, sizeof(path), "%s%s", htdocs, requested_uri); - - /* refuse to serve files we don't understand */ - char *mimetype = get_mimetype(path); - if (!mimetype) { - warn("HTTP: Unknown mimetype for %s", path); - lws_return_http_status(wsi, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, NULL); - return -1; - } - - int n = lws_serve_http_file(wsi, path, mimetype, NULL, 0); - if (n < 0) - return -1; - else if (n == 0) - break; - else - goto try_to_reuse; - } - - default: - break; - } - - return 0; - -try_to_reuse: - if (lws_http_transaction_completed(wsi)) - return -1; - - return 0; -} - -int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { struct websocket_connection *c = user; struct websocket *w; @@ -364,61 +149,6 @@ int protocol_cb_live(struct lws *wsi, enum lws_callback_reasons reason, void *us } } -int websocket_init(int argc, char * argv[], config_setting_t *cfg) -{ - config_setting_t *cfg_http; - - lws_set_log_level((1 << LLL_COUNT) - 1, logger); - - /* Parse global config */ - cfg_http = config_setting_lookup(cfg, "http"); - if (cfg_http) { - config_setting_lookup_string(cfg_http, "ssl_cert", &ssl_cert); - config_setting_lookup_string(cfg_http, "ssl_private_key", &ssl_private_key); - config_setting_lookup_string(cfg_http, "htdocs", &htdocs); - config_setting_lookup_int(cfg_http, "port", &port); - } - - /* Default settings */ - if (!port) - port = 80; - if (!htdocs) - htdocs = "/villas/contrib/websocket"; - - /* Start server */ - struct lws_context_creation_info info = { - .port = port, - .protocols = protocols, - .extensions = NULL, //exts, - .ssl_cert_filepath = ssl_cert, - .ssl_private_key_filepath = ssl_private_key, - .gid = -1, - .uid = -1 - }; - - context = lws_create_context(&info); - if (context == NULL) - error("WebSocket: failed to initialize server"); - - /* Save root config for GET /config.json request */ - cfg_root = cfg; - - pthread_create(&thread, NULL, server_thread, NULL); - - return 0; -} - -int websocket_deinit() -{ - lws_cancel_service(context); - lws_context_destroy(context); - - pthread_cancel(thread); - pthread_join(thread, NULL); - - return 0; -} - int websocket_open(struct node *n) { struct websocket *w = n->_vd; diff --git a/lib/web.c b/lib/web.c new file mode 100644 index 000000000..a44da1072 --- /dev/null +++ b/lib/web.c @@ -0,0 +1,184 @@ +/** LWS-releated functions. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + *********************************************************************************/ + +#include +#include + +#include + +#if 0 + #include "nodes/websocket.h" +#endif + +#include "utils.h" +#include "log.h" +#include "web.h" +#include "api.h" + +/* Forward declarations */ +lws_callback_function api_protocol_cb; + +/** Path to the directory which should be served by build in HTTP server */ +static char htdocs[PATH_MAX] = "/usr/local/share/villas/node/htdocs"; + +/** List of libwebsockets protocols. */ +static struct lws_protocols protocols[] = { + { + .name = "http-only", + .callback = api_protocol_cb, + .per_session_data_size = sizeof(struct api_session), + .rx_buffer_size = 0 + }, +#if 0 + { + .name = "live", + .callback = websocket_protocol_cb, + .per_session_data_size = sizeof(struct websocket_connection), + .rx_buffer_size = 0 + }, +#endif + { + .name = "api", + .callback = api_protocol_cb, + .per_session_data_size = sizeof(struct api_session), + .rx_buffer_size = 0 + }, + { 0 /* terminator */ } +}; + +/** List of libwebsockets mounts. */ +static struct lws_http_mount mounts[] = { + { + .mount_next = &mounts[1], + .mountpoint = "/api/v1/", + .origin = "cmd", + .def = NULL, + .cgienv = NULL, + .cgi_timeout = 0, + .cache_max_age = 0, + .cache_reusable = 0, + .cache_revalidate = 0, + .cache_intermediaries = 0, + .origin_protocol = LWSMPRO_CALLBACK, + .mountpoint_len = 8 + }, + { + .mount_next = NULL, + .mountpoint = "/", + .origin = htdocs, + .def = "/index.html", + .cgienv = NULL, + .cgi_timeout = 0, + .cache_max_age = 0, + .cache_reusable = 0, + .cache_revalidate = 0, + .cache_intermediaries = 0, + .origin_protocol = LWSMPRO_FILE, + .mountpoint_len = 1 + } +}; + +/** List of libwebsockets extensions. */ +static const struct lws_extension extensions[] = { + { + "permessage-deflate", + lws_extension_callback_pm_deflate, + "permessage-deflate" + }, + { + "deflate-frame", + lws_extension_callback_pm_deflate, + "deflate_frame" + }, + { NULL /* terminator */ } +}; + +static void logger(int level, const char *msg) { + int len = strlen(msg); + if (strchr(msg, '\n')) + len -= 1; + + /* Decrease severity for some errors. */ + if (strstr(msg, "Unable to open") == msg) + level = LLL_WARN; + + switch (level) { + case LLL_ERR: error("LWS: %.*s", len, msg); break; + case LLL_WARN: warn("LWS: %.*s", len, msg); break; + case LLL_INFO: info("LWS: %.*s", len, msg); break; + default: debug(LOG_WEBSOCKET | 1, "LWS: %.*s", len, msg); break; + } +} + +int web_service(struct web *w) +{ + return lws_service(w->context, 10); +} + +int web_parse(struct web *w, config_setting_t *lcs) +{ + config_setting_t *lcs_http; + + /* Parse global config */ + lcs_http = config_setting_lookup(lcs, "http"); + if (lcs_http) { + const char *ht; + + config_setting_lookup_string(lcs_http, "ssl_cert", &w->ssl_cert); + config_setting_lookup_string(lcs_http, "ssl_private_key", &w->ssl_private_key); + config_setting_lookup_int(lcs_http, "port", &w->port); + + if (config_setting_lookup_string(lcs_http, "htdocs", &w->htdocs)) { + strncpy(htdocs, ht, sizeof(htdocs)); + } + } + + return 0; +} + +int web_init(struct web *w, struct api *a) +{ + w->api = a; + + lws_set_log_level((1 << LLL_COUNT) - 1, logger); + + /* Start server */ + struct lws_context_creation_info ctx_info = { + .options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS, + .gid = -1, + .uid = -1, + .user = (void *) w + }; + + struct lws_context_creation_info vhost_info = { + .protocols = protocols, + .mounts = mounts, + .extensions = extensions, + .port = w->port, + .ssl_cert_filepath = w->ssl_cert, + .ssl_private_key_filepath = w->ssl_private_key + }; + + w->context = lws_create_context(&ctx_info); + if (w->context == NULL) + error("WebSocket: failed to initialize server"); + + w->vhost = lws_create_vhost(w->context, &vhost_info); + if (w->vhost == NULL) + error("WebSocket: failed to initialize server"); + + return 0; +} + +int web_deinit(struct web *w) +{ + lws_cancel_service(w->context); + lws_context_destroy(w->context); + + return 0; +} From c930ad49b7ea373c8cd952e1222b4a1732d5e244 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:58:17 -0500 Subject: [PATCH 089/211] several smaller changes and bugfixes --- etc/fpga-simple.conf | 70 +++++++++++++++++---------------- include/villas/hooks.h | 4 +- include/villas/kernel/vfio.h | 1 + lib/advio.c | 22 ++++++----- lib/kernel/pci.c | 2 + lib/path.c | 13 ++++++ plugins/hooks/example_hook.c | 8 +++- plugins/models/simple_circuit.c | 2 +- src/node.c | 47 ++++++++++++++++------ 9 files changed, 108 insertions(+), 61 deletions(-) diff --git a/etc/fpga-simple.conf b/etc/fpga-simple.conf index 7135b895b..530971f25 100644 --- a/etc/fpga-simple.conf +++ b/etc/fpga-simple.conf @@ -17,44 +17,46 @@ @include "global.conf" @include "plugins.conf" -fpga = { - /* Card identification */ - id = "10ee:7022"; - slot = "01:00.0"; +fpgas = { + vc707 = { + /* Card identification */ + id = "10ee:7022"; + slot = "01:00.0"; - intc = 0x5000; - reset = 0x2000; - do_reset = true; + intc = 0x5000; + reset = 0x2000; + do_reset = true; - ips = { - switch_0 = { - vlnv = "xilinx.com:ip:axis_interconnect:2.1" - baseaddr = 0x0000; - numports = 3; - }, - rtds_0 = { - vlnv = "acs.eonerc.rwth-aachen.de:user:rtds_axis:1.0" - baseaddr = 0x3000; - port = 0; - }, - dma_0 = { - vlnv = "xilinx.com:ip:axi_dma:7.1"; - baseaddr = 0x1000; - port = 2; - irq = 0 - }, - hls_dft_0 = { - vlnv = "acs.eonerc.rwth-aachen.de:hls:hls_dft:1.0"; - port = 1; - switch = "switch_0"; + ips = { + switch_0 = { + vlnv = "xilinx.com:ip:axis_interconnect:2.1" + baseaddr = 0x0000; + numports = 3; + }, + rtds_0 = { + vlnv = "acs.eonerc.rwth-aachen.de:user:rtds_axis:1.0" + baseaddr = 0x3000; + port = 0; + }, + dma_0 = { + vlnv = "xilinx.com:ip:axi_dma:7.1"; + baseaddr = 0x1000; + port = 2; + irq = 0 + }, + hls_dft_0 = { + vlnv = "acs.eonerc.rwth-aachen.de:hls:hls_dft:1.0"; + port = 1; + switch = "switch_0"; + } } - } - /* Configure switch */ - paths = ( - { in = "dma", out = "hls_dft" }, - { in = "hls_dft", out = "dma" } - ) + /* Configure switch */ + paths = ( + { in = "dma", out = "hls_dft" }, + { in = "hls_dft", out = "dma" } + ) + } } nodes = { diff --git a/include/villas/hooks.h b/include/villas/hooks.h index dd9b70bfb..b80daef1a 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -150,6 +150,4 @@ void hook_stats_header(); int hook_fix_ts(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); int hook_restart(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); -int hook_drop(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); - -#endif /** _HOOKS_H_ @} */ +int hook_drop(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt); \ No newline at end of file diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 68c3c559e..ea84ada0e 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -9,6 +9,7 @@ #pragma once +#include #include #include diff --git a/lib/advio.c b/lib/advio.c index fa00b10e5..9ec093cbd 100644 --- a/lib/advio.c +++ b/lib/advio.c @@ -50,6 +50,7 @@ AFILE *afopen(const char *uri, const char *mode, int flags) if (!af->curl) goto out1; + curl_easy_setopt(af->curl, CURLOPT_DEFAULT_PROTOCOL, "file"); curl_easy_setopt(af->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(af->curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(af->curl, CURLOPT_USERAGENT, USER_AGENT); @@ -59,16 +60,10 @@ AFILE *afopen(const char *uri, const char *mode, int flags) res = curl_easy_perform(af->curl); switch (res) { case CURLE_OK: - switch (mode[0]) { - case 'w': - case 'r': - fseek(af->file, 0, SEEK_SET); - break; - - case 'a': - fseek(af->file, 0, SEEK_END); - break; - } + if (mode[0] == 'a') + fseek(af->file, 0, SEEK_END); + else if (mode[0] == 'r' || mode[0] == 'w') + fseek(af->file, 0, SEEK_SET); break; /* The following error codes indicate that the file does not exist @@ -79,7 +74,14 @@ AFILE *afopen(const char *uri, const char *mode, int flags) if (mode[0] == 'a' || (mode[0] == 'w' && mode[1] == '+')) break; /* its okay */ + /* If libcurl does not know the protocol, we will try it with the stdio */ + case CURLE_UNSUPPORTED_PROTOCOL: + af->file = fopen(uri, mode); + if (!af->file) + goto out2; + default: + printf("avdio: %s\n", curl_easy_strerror(res)); goto out0; /* no please fail here */ } diff --git a/lib/kernel/pci.c b/lib/kernel/pci.c index a40c5158b..327a3be36 100644 --- a/lib/kernel/pci.c +++ b/lib/kernel/pci.c @@ -58,6 +58,8 @@ int pci_init(struct pci *p) ret = sscanf(entry->d_name, "%4x:%2x:%2x.%u", &d.slot.domain, &d.slot.bus, &d.slot.device, &d.slot.function); if (ret != 4) error("Failed to parse PCI slot number: %s", entry->d_name); + + list_push(&p->devices, memdup(&d, sizeof(d))); } closedir(dp); diff --git a/lib/path.c b/lib/path.c index d860ceac1..82cf0b24d 100644 --- a/lib/path.c +++ b/lib/path.c @@ -212,6 +212,19 @@ int path_destroy(struct path *p) return 0; } +int path_check(struct path *p) +{ + list_foreach (struct node *n, &p->destinations) { + if (!n->_vt->write) + error("Destiation node '%s' is not supported as a sink for path '%s'", node_name(n), path_name(p)); + } + + if (!p->in->_vt->read) + error("Source node '%s' is not supported as source for path '%s'", node_name(p->in), path_name(p)); + + return 0; +} + int path_prepare(struct path *p) { int ret; diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index f63b0e4c6..b3dbeda67 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -1,6 +1,10 @@ -#include +#include #include -#include +#include + +struct hook; +struct path; +struct sample; static int hook_example(struct path *p, struct hook *h, int when, struct sample *smps[], size_t cnt) { diff --git a/plugins/models/simple_circuit.c b/plugins/models/simple_circuit.c index 4e3b66567..049b7e8a6 100644 --- a/plugins/models/simple_circuit.c +++ b/plugins/models/simple_circuit.c @@ -158,7 +158,7 @@ int simple_circuit_write(float inputs[], int len) static struct plugin p = { .name = "simple_circuit", .description = "A simple CBuilder model", - .type = LOADABLE_TYPE_MODEL_CBUILDER, + .type = PLUGIN_TYPE_MODEL_CBUILDER, .cb = { .code = simple_circuit_code, .init = simple_circuit_init, diff --git a/src/node.c b/src/node.c index 29528e072..28e41f5f2 100644 --- a/src/node.c +++ b/src/node.c @@ -16,9 +16,15 @@ #include #include #include +#include +#include +#include #include #include +/* Forward declarations */ +void hook_stats_header(); + #ifdef ENABLE_OPAL_ASYNC #include "opal.h" #endif @@ -60,8 +66,10 @@ static void signals_init() static void usage(const char *name) { - printf("Usage: %s CONFIG\n", name); - printf(" CONFIG is a required path to a configuration file\n\n"); + printf("Usage: %s [CONFIG]\n", name); + printf(" CONFIG is the path to an optional configuration file\n"); + printf(" if omitted, VILLASnode will start without a configuration\n"); + printf(" and wait for provisioning over the web interface.\n\n"); #ifdef ENABLE_OPAL_ASYNC printf("Usage: %s OPAL_ASYNC_SHMEM_NAME OPAL_ASYNC_SHMEM_SIZE OPAL_PRINT_SHMEM_NAME\n", name); printf(" This type of invocation is used by OPAL-RT Asynchronous processes.\n"); @@ -76,6 +84,11 @@ static void usage(const char *name) list_foreach(struct hook *h, &hooks) printf(" - %s: %s\n", h->name, h->description); printf("\n"); + + printf("Supported API commands:\n"); + list_foreach(struct api_ressource *r, &apis) + printf(" - %s: %s\n", r->name, r->description); + printf("\n"); print_copyright(); @@ -86,11 +99,16 @@ int main(int argc, char *argv[]) { /* Check arguments */ #ifdef ENABLE_OPAL_ASYNC - if (argc != 2 && argc != 4) -#else - if (argc != 2) -#endif + if (argc != 4) usage(argv[0]); + + char *uri = "opal-shmem.conf"; +#else + if (argc > 2) + usage(argv[0]); + + char *uri = (argc == 2) ? argv[1] : NULL; +#endif info("This is VILLASnode %s (built on %s, %s)", BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__))); @@ -138,14 +156,21 @@ int main(int argc, char *argv[]) if (config.stats > 0) hook_stats_header(); - for (;;) { - list_foreach(struct path *p, &paths) + struct timespec now, last = time_now(); + + /* Run! Until signal handler is invoked */ + while (1) { + now = time_now(); + if (config.stats > 0 && time_delta(&last, &now) > config.stats) { + list_foreach(struct path *p, &config.paths) { hook_run(p, NULL, 0, HOOK_PERIODIC); - usleep(settings.stats * 1e6); + } + + last = time_now(); } + + web_service(&config.web); /** @todo Maybe we should move this to another thread */ } - else - pause(); return 0; } From 755950a5d1afeeb46ac239f001f7b384845d0010 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 18 Feb 2017 10:58:40 -0500 Subject: [PATCH 090/211] updated libwebsockets submodule --- thirdparty/libwebsockets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/libwebsockets b/thirdparty/libwebsockets index 0c984014f..0d1170b44 160000 --- a/thirdparty/libwebsockets +++ b/thirdparty/libwebsockets @@ -1 +1 @@ -Subproject commit 0c984014f0a82e184af2ff18f97b45e2cbccd0bd +Subproject commit 0d1170b449a2b867901c3f8b5cef7aae9a5c122d From 3e7c855526a8572674f11513e075f14465ce3094 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 3 Mar 2017 20:20:13 -0400 Subject: [PATCH 091/211] updated licence and copyright info in file headers --- .../udp/models/send_receive/include/msg.h | 2 +- .../models/send_receive/include/msg_format.h | 2 +- .../udp/models/send_receive/include/utils.h | 2 +- .../opal/udp/models/send_receive/src/msg.c | 2 +- .../opal/udp/models/send_receive/src/utils.c | 2 +- config.h | 2 +- include/villas/advio.h | 20 +++++++++++++++++-- include/villas/api.h | 2 -- include/villas/cfg.h | 2 +- include/villas/fpga/card.h | 12 ++++------- include/villas/fpga/ip.h | 12 ++++------- include/villas/fpga/ips/dft.h | 10 ++++------ include/villas/fpga/ips/dma.h | 8 +++----- include/villas/fpga/ips/fifo.h | 7 ++----- include/villas/fpga/ips/intc.h | 8 +++----- include/villas/fpga/ips/model.h | 8 +++----- include/villas/fpga/ips/rtds_axis.h | 8 +++----- include/villas/fpga/ips/switch.h | 8 +++----- include/villas/fpga/ips/timer.h | 8 +++----- include/villas/fpga/vlnv.h | 10 +++------- include/villas/hist.h | 2 +- include/villas/hooks.h | 2 +- include/villas/kernel/if.h | 8 ++++++-- include/villas/kernel/kernel.h | 8 ++++++-- include/villas/kernel/nl.h | 8 ++++++-- include/villas/kernel/pci.h | 8 ++++++-- include/villas/kernel/rt.h | 8 ++++++-- include/villas/kernel/tc.h | 8 ++++++-- include/villas/kernel/vfio.h | 8 ++++++-- include/villas/list.h | 2 +- include/villas/log.h | 2 +- include/villas/memory.h | 4 ++-- include/villas/msg.h | 2 +- include/villas/msg_format.h | 2 +- include/villas/node.h | 2 +- include/villas/nodes/cbuilder.h | 11 +++++----- include/villas/nodes/file.h | 8 ++++---- include/villas/nodes/fpga.h | 7 ++++--- include/villas/nodes/ngsi.h | 7 ++++--- include/villas/nodes/opal.h | 7 ++++--- include/villas/nodes/socket.h | 7 ++++--- include/villas/nodes/websocket.h | 7 ++++--- include/villas/path.h | 2 +- include/villas/plugin.h | 2 -- include/villas/pool.h | 4 ++-- include/villas/queue.h | 4 ++-- include/villas/sample.h | 4 ++-- include/villas/timing.h | 2 +- include/villas/utils.h | 2 +- include/villas/web.h | 2 -- lib/advio.c | 4 +--- lib/api.c | 2 -- lib/cfg.c | 2 +- lib/fpga/card.c | 6 ++++++ lib/fpga/ip.c | 6 ++++++ lib/fpga/ips/dft.c | 2 +- lib/fpga/ips/dma.c | 2 +- lib/fpga/ips/fifo.c | 2 +- lib/fpga/ips/intc.c | 2 +- lib/fpga/ips/model.c | 2 +- lib/fpga/ips/rtds_axis.c | 2 +- lib/fpga/ips/switch.c | 2 +- lib/fpga/ips/timer.c | 2 +- lib/fpga/vlnv.c | 5 +---- lib/hist.c | 2 +- lib/hooks.c | 2 +- lib/hooks/hooks-internal.c | 2 +- lib/hooks/hooks-other.c | 2 +- lib/hooks/hooks-stats.c | 2 +- lib/kernel/if.c | 2 +- lib/kernel/kernel.c | 2 +- lib/kernel/nl.c | 2 +- lib/kernel/pci.c | 2 +- lib/kernel/rt.c | 2 +- lib/kernel/tc.c | 2 +- lib/kernel/vfio.c | 2 +- lib/list.c | 2 +- lib/log.c | 2 +- lib/memory.c | 4 ++-- lib/msg.c | 2 +- lib/node.c | 2 +- lib/nodes/cbuilder.c | 2 +- lib/nodes/file.c | 2 +- lib/nodes/fpga.c | 2 +- lib/nodes/ngsi.c | 2 +- lib/nodes/opal.c | 2 +- lib/nodes/socket.c | 2 +- lib/nodes/websocket.c | 2 +- lib/path.c | 2 +- lib/plugin.c | 4 +--- lib/pool.c | 4 ++-- lib/queue.c | 4 ++-- lib/sample.c | 2 +- lib/timing.c | 2 +- lib/utils.c | 2 +- lib/web.c | 2 -- plugins/hooks/example_hook.c | 6 ++++++ plugins/models/simple_circuit.c | 8 +++++--- src/fpga-bench-overruns.c | 2 +- src/fpga-bench.c | 2 +- src/fpga-tests.c | 2 +- src/fpga.c | 2 +- src/node.c | 2 +- src/pipe.c | 2 +- src/signal.c | 2 +- src/test.c | 2 +- tests/advio.c | 6 ++++++ tests/hist.c | 2 +- tests/list.c | 2 +- tests/memory.c | 2 +- tests/pool.c | 2 +- tests/queue.c | 6 ++++++ tests/timing.c | 2 +- tests/utils.c | 2 +- 114 files changed, 244 insertions(+), 208 deletions(-) diff --git a/clients/opal/udp/models/send_receive/include/msg.h b/clients/opal/udp/models/send_receive/include/msg.h index e68bd1b26..ee00377ab 100644 --- a/clients/opal/udp/models/send_receive/include/msg.h +++ b/clients/opal/udp/models/send_receive/include/msg.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #ifndef _MSG_H_ diff --git a/clients/opal/udp/models/send_receive/include/msg_format.h b/clients/opal/udp/models/send_receive/include/msg_format.h index 72951d01f..2b1b5cc79 100644 --- a/clients/opal/udp/models/send_receive/include/msg_format.h +++ b/clients/opal/udp/models/send_receive/include/msg_format.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #ifndef _MSG_FORMAT_H_ diff --git a/clients/opal/udp/models/send_receive/include/utils.h b/clients/opal/udp/models/send_receive/include/utils.h index bc70e4f0f..f1c387d50 100644 --- a/clients/opal/udp/models/send_receive/include/utils.h +++ b/clients/opal/udp/models/send_receive/include/utils.h @@ -4,7 +4,7 @@ * @author Steffen Vogel * @author Mathieu Dubé-Dallaire * @copyright 2003, OPAL-RT Technologies inc - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #ifndef _UTILS_H_ diff --git a/clients/opal/udp/models/send_receive/src/msg.c b/clients/opal/udp/models/send_receive/src/msg.c index 5c2bf19a8..dd472514e 100644 --- a/clients/opal/udp/models/send_receive/src/msg.c +++ b/clients/opal/udp/models/send_receive/src/msg.c @@ -1,7 +1,7 @@ /** Message related functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #ifdef __linux__ diff --git a/clients/opal/udp/models/send_receive/src/utils.c b/clients/opal/udp/models/send_receive/src/utils.c index 645124740..e8c599807 100644 --- a/clients/opal/udp/models/send_receive/src/utils.c +++ b/clients/opal/udp/models/send_receive/src/utils.c @@ -4,7 +4,7 @@ * @author Steffen Vogel * @author Mathieu Dubé-Dallaire * @copyright 2003, OPAL-RT Technologies inc - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/config.h b/config.h index a411f63cf..efb6d2984 100644 --- a/config.h +++ b/config.h @@ -5,7 +5,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/advio.h b/include/villas/advio.h index b4ab47bcc..c500656d5 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -1,6 +1,22 @@ -/** Advanced IO +/** libcurl based remote IO * - */ + * Implements an fopen() abstraction allowing reading from URLs + * + * This file introduces a c library buffered I/O interface to + * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(), + * rewind(). Supported functions have identical prototypes to their normal c + * lib namesakes and are preceaded by a . + * + * Using this code you can replace your program's fopen() with afopen() + * and fread() with afread() and it become possible to read remote streams + * instead of (only) local files. Local files (ie those that can be directly + * fopened) will drop back to using the underlying clib implementations + * + * This example requires libcurl 7.9.7 or later. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #pragma once diff --git a/include/villas/api.h b/include/villas/api.h index f75bc3426..c4a421799 100644 --- a/include/villas/api.h +++ b/include/villas/api.h @@ -3,8 +3,6 @@ * @file * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ #pragma once diff --git a/include/villas/cfg.h b/include/villas/cfg.h index aeea35b8c..b2c432d93 100644 --- a/include/villas/cfg.h +++ b/include/villas/cfg.h @@ -6,7 +6,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/fpga/card.h b/include/villas/fpga/card.h index 8fa9815d4..707948640 100644 --- a/include/villas/fpga/card.h +++ b/include/villas/fpga/card.h @@ -4,14 +4,10 @@ * * @file * @author Steffen Vogel - * @copyright 2017, Steffen Vogel - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - */ -/** - * @addtogroup fpga VILLASfpga - * @{ - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + +/** @addtogroup fpga VILLASfpga @{ */ #pragma once diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index fb0e94a88..3f8c6ff77 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -4,14 +4,10 @@ * * @file * @author Steffen Vogel - * @copyright 2015-2016, Steffen Vogel - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - */ -/** - * @addtogroup fpga VILLASfpga - * @{ - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + +/** @addtogroup fpga VILLASfpga @{ */ #pragma once diff --git a/include/villas/fpga/ips/dft.h b/include/villas/fpga/ips/dft.h index d36ca2882..f8ac4910d 100644 --- a/include/villas/fpga/ips/dft.h +++ b/include/villas/fpga/ips/dft.h @@ -2,12 +2,10 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ - **********************************************************************************/ + * @copyright 2017, Steffen Vogel +**********************************************************************************/ + +/** @addtogroup fpga VILLASfpga @{ */ #pragma once diff --git a/include/villas/fpga/ips/dma.h b/include/villas/fpga/ips/dma.h index e26b1385e..d42d4d885 100644 --- a/include/villas/fpga/ips/dma.h +++ b/include/villas/fpga/ips/dma.h @@ -4,13 +4,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once #include diff --git a/include/villas/fpga/ips/fifo.h b/include/villas/fpga/ips/fifo.h index 119e57522..c7af8eb49 100644 --- a/include/villas/fpga/ips/fifo.h +++ b/include/villas/fpga/ips/fifo.h @@ -4,13 +4,10 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ #pragma once diff --git a/include/villas/fpga/ips/intc.h b/include/villas/fpga/ips/intc.h index dd1efe88e..4af79a068 100644 --- a/include/villas/fpga/ips/intc.h +++ b/include/villas/fpga/ips/intc.h @@ -1,13 +1,11 @@ /** AXI-PCIe Interrupt controller * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once #include diff --git a/include/villas/fpga/ips/model.h b/include/villas/fpga/ips/model.h index 5b336a62f..60725589f 100644 --- a/include/villas/fpga/ips/model.h +++ b/include/villas/fpga/ips/model.h @@ -2,13 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel *********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once #include diff --git a/include/villas/fpga/ips/rtds_axis.h b/include/villas/fpga/ips/rtds_axis.h index a44a5171e..b81759e26 100644 --- a/include/villas/fpga/ips/rtds_axis.h +++ b/include/villas/fpga/ips/rtds_axis.h @@ -2,13 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once /* Forward declarations */ diff --git a/include/villas/fpga/ips/switch.h b/include/villas/fpga/ips/switch.h index 5ae4bae35..0d09cb7a2 100644 --- a/include/villas/fpga/ips/switch.h +++ b/include/villas/fpga/ips/switch.h @@ -4,13 +4,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once #include diff --git a/include/villas/fpga/ips/timer.h b/include/villas/fpga/ips/timer.h index 97ecad38b..cf5e3779e 100644 --- a/include/villas/fpga/ips/timer.h +++ b/include/villas/fpga/ips/timer.h @@ -4,13 +4,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ -/** - * @addtogroup fpga VILLASfpga - * @{ + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga VILLASfpga @{ */ + #pragma once #include diff --git a/include/villas/fpga/vlnv.h b/include/villas/fpga/vlnv.h index 2abf2721e..fa77555d7 100644 --- a/include/villas/fpga/vlnv.h +++ b/include/villas/fpga/vlnv.h @@ -3,13 +3,9 @@ * @file * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - */ -/** - * @addtogroup fpga VILLASfpga - * @{ - */ + *********************************************************************************/ + +/** @addtogroup fpga VILLASfpga @{ */ #ifndef _FPGA_VLNV_H_ #define _FPGA_VLNV_H_ diff --git a/include/villas/hist.h b/include/villas/hist.h index 6a5d480d7..f40d8b068 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/hooks.h b/include/villas/hooks.h index c153eb787..3a8febbfd 100644 --- a/include/villas/hooks.h +++ b/include/villas/hooks.h @@ -8,7 +8,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC */ /** * @addtogroup hooks User-defined hook functions diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h index 11018903b..f1c964b1c 100644 --- a/include/villas/kernel/if.h +++ b/include/villas/kernel/if.h @@ -5,9 +5,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include @@ -101,4 +103,6 @@ int if_get_irqs(struct interface *i); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int if_set_affinity(struct interface *i, int affinity); \ No newline at end of file +int if_set_affinity(struct interface *i, int affinity); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index cf89427b3..ee79010f4 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -2,9 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include @@ -55,4 +57,6 @@ int kernel_module_set_param(const char *module, const char *param, const char *v int kernel_get_cacheline_size(); /** Set SMP affinity of IRQ */ -int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); \ No newline at end of file +int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/nl.h b/include/villas/kernel/nl.h index 080a7f56f..83fe7245d 100644 --- a/include/villas/kernel/nl.h +++ b/include/villas/kernel/nl.h @@ -2,9 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include @@ -22,4 +24,6 @@ int nl_get_egress(struct nl_addr *addr); struct nl_sock * nl_init(); /** Close and free global netlink socket. */ -void nl_shutdown(); \ No newline at end of file +void nl_shutdown(); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h index 5de084992..6999aefbf 100644 --- a/include/villas/kernel/pci.h +++ b/include/villas/kernel/pci.h @@ -2,9 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include "list.h" @@ -55,4 +57,6 @@ struct pci_dev * pci_lookup_device(struct pci *p, struct pci_dev *filter); int pci_attach_driver(struct pci_dev *d, const char *driver); /** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */ -int pci_get_iommu_group(struct pci_dev *d); \ No newline at end of file +int pci_get_iommu_group(struct pci_dev *d); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index 1bf4a667e..723b6582a 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -2,9 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once int rt_init(struct cfg *cfg); @@ -20,4 +22,6 @@ int rt_set_priority(int priority); * @retval 0 Kernel is patched. * @reval <>0 Kernel is not patched. */ -int rt_is_preemptible(); \ No newline at end of file +int rt_is_preemptible(); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h index b23cdd1a3..d7f017c5b 100644 --- a/include/villas/kernel/tc.h +++ b/include/villas/kernel/tc.h @@ -7,9 +7,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include @@ -79,4 +81,6 @@ int tc_netem(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hd * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark); \ No newline at end of file +int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark); + +/** @} */ \ No newline at end of file diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h index 2c5f723e0..f18a4f8e4 100644 --- a/include/villas/kernel/vfio.h +++ b/include/villas/kernel/vfio.h @@ -2,9 +2,11 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel *********************************************************************************/ +/** @addtogroup fpga Kernel @{ */ + #pragma once #include @@ -105,4 +107,6 @@ int vfio_map_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t int vfio_unmap_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len); /** munmap() a region which has been mapped by vfio_map_region() */ -int vfio_unmap_region(struct vfio_dev *d, int idx); \ No newline at end of file +int vfio_unmap_region(struct vfio_dev *d, int idx); + +/** @} */ \ No newline at end of file diff --git a/include/villas/list.h b/include/villas/list.h index f82e8f843..7d15bf941 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -8,7 +8,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 20177, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/log.h b/include/villas/log.h index c37cc3b39..0cf8b5433 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/memory.h b/include/villas/memory.h index 978411b6d..c4cc950b4 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -2,8 +2,8 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #include #include diff --git a/include/villas/msg.h b/include/villas/msg.h index 26b7a90bd..130e06be1 100644 --- a/include/villas/msg.h +++ b/include/villas/msg.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/msg_format.h b/include/villas/msg_format.h index 11545bf29..e63f90db0 100644 --- a/include/villas/msg_format.h +++ b/include/villas/msg_format.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/node.h b/include/villas/node.h index a4ff7cd71..b0cac153e 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC * * @addtogroup node Node * @{ diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index 35a32bb50..fb2675ed8 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -2,14 +2,15 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ + * @copyright 2017, Steffen Vogel + *********************************************************************************/ + /** * @addtogroup cbuilder RTDS CBuilder model node * @ingroup node - * @{ - *********************************************************************************/ - + * @{ + */ + #pragma once #include diff --git a/include/villas/nodes/file.h b/include/villas/nodes/file.h index a42b4453b..0804691aa 100644 --- a/include/villas/nodes/file.h +++ b/include/villas/nodes/file.h @@ -4,14 +4,14 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + /** * @addtogroup file File-IO node type * @ingroup node * @{ - *********************************************************************************/ - + */ #pragma once diff --git a/include/villas/nodes/fpga.h b/include/villas/nodes/fpga.h index 5d09dd3db..aa331c709 100644 --- a/include/villas/nodes/fpga.h +++ b/include/villas/nodes/fpga.h @@ -4,13 +4,14 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel - */ + * @copyright 2017, Steffen Vogel + *********************************************************************************/ + /** * @addtogroup fpga VILLASfpga * @ingroup node * @{ - *********************************************************************************/ + */ #pragma once diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index 2c683db2d..ad1ddd489 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -8,13 +8,14 @@ * @see http://technical.openmobilealliance.org/Technical/Release_Program/docs/NGSI/V1_0-20120529-A/OMA-TS-NGSI_Context_Management-V1_0-20120529-A.pdf * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + /** * @addtogroup ngsi FIRWARE NGSI 9/10 RESTful HTTP API * @ingroup node * @{ - **********************************************************************************/ + */ #pragma once diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index 85328bfb9..21a8afa92 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -4,13 +4,14 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + /** * @ingroup node * @addtogroup opal OPAL-RT Async Process node type * @{ - **********************************************************************************/ + */ #pragma once diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 86a303ae7..9a8f228b4 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -4,13 +4,14 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + /** * @addtogroup socket BSD Socket Node Type * @ingroup node * @{ - *********************************************************************************/ + */ #pragma once diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 413c9954d..0d80f6a12 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -5,13 +5,14 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + /** * @addtogroup websockets WebSockets node type * @ingroup node * @{ - *********************************************************************************/ + */ #pragma once diff --git a/include/villas/path.h b/include/villas/path.h index 97e7803e5..bccc7ff64 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC */ /** A path connects one input node to multiple output nodes (1-to-n). * diff --git a/include/villas/plugin.h b/include/villas/plugin.h index 5085ad6bd..a138527ab 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -3,8 +3,6 @@ * @file * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ #pragma once diff --git a/include/villas/pool.h b/include/villas/pool.h index a6775100e..f54f43081 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -4,8 +4,8 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #pragma once diff --git a/include/villas/queue.h b/include/villas/queue.h index 3b42989be..b1e4f6ce0 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -4,7 +4,7 @@ * http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue * * @author Steffen Vogel - * @copyright 2016 Steffen Vogel + * @copyright 2017 Steffen Vogel * @license BSD 2-Clause License * * All rights reserved. @@ -29,7 +29,7 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + *********************************************************************************/ #pragma once diff --git a/include/villas/sample.h b/include/villas/sample.h index acf6c8ddd..bc7519f43 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -2,8 +2,8 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #pragma once diff --git a/include/villas/timing.h b/include/villas/timing.h index b00921865..5872a7d40 100644 --- a/include/villas/timing.h +++ b/include/villas/timing.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/utils.h b/include/villas/utils.h index 1f1ffa2e0..bd5c57a38 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #pragma once diff --git a/include/villas/web.h b/include/villas/web.h index 81826b25b..f9c720393 100644 --- a/include/villas/web.h +++ b/include/villas/web.h @@ -3,8 +3,6 @@ * @file * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ #pragma once diff --git a/lib/advio.c b/lib/advio.c index 9ec093cbd..50ee72e6e 100644 --- a/lib/advio.c +++ b/lib/advio.c @@ -15,9 +15,7 @@ * This example requires libcurl 7.9.7 or later. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/api.c b/lib/api.c index dc9efca0d..39468d3a5 100644 --- a/lib/api.c +++ b/lib/api.c @@ -2,8 +2,6 @@ * * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ #include diff --git a/lib/cfg.c b/lib/cfg.c index 85745e5c6..111d3ff93 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -1,7 +1,7 @@ /** Configuration parser. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/fpga/card.c b/lib/fpga/card.c index 02c5d5de6..44636a73b 100644 --- a/lib/fpga/card.c +++ b/lib/fpga/card.c @@ -1,3 +1,9 @@ +/** FPGA card. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + #include #include "config.h" diff --git a/lib/fpga/ip.c b/lib/fpga/ip.c index 9fcf16ae0..42dfb56de 100644 --- a/lib/fpga/ip.c +++ b/lib/fpga/ip.c @@ -1,3 +1,9 @@ +/** FPGA IP component. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + #include #include "log.h" diff --git a/lib/fpga/ips/dft.c b/lib/fpga/ips/dft.c index 6152799ed..2ce6c8c6b 100644 --- a/lib/fpga/ips/dft.c +++ b/lib/fpga/ips/dft.c @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include "log.h" diff --git a/lib/fpga/ips/dma.c b/lib/fpga/ips/dma.c index b810e507c..b01ba4e10 100644 --- a/lib/fpga/ips/dma.c +++ b/lib/fpga/ips/dma.c @@ -3,7 +3,7 @@ * These functions present a simpler interface to Xilinx' DMA driver (XAxiDma_*) * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/lib/fpga/ips/fifo.c b/lib/fpga/ips/fifo.c index c53a70920..5d2dc137d 100644 --- a/lib/fpga/ips/fifo.c +++ b/lib/fpga/ips/fifo.c @@ -3,7 +3,7 @@ * These functions present a simpler interface to Xilinx' FIFO driver (XLlFifo_*) * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/lib/fpga/ips/intc.c b/lib/fpga/ips/intc.c index 83dd51b77..22c596fc3 100644 --- a/lib/fpga/ips/intc.c +++ b/lib/fpga/ips/intc.c @@ -1,7 +1,7 @@ /** AXI-PCIe Interrupt controller * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/lib/fpga/ips/model.c b/lib/fpga/ips/model.c index beeee09ce..6d91293bb 100644 --- a/lib/fpga/ips/model.c +++ b/lib/fpga/ips/model.c @@ -1,7 +1,7 @@ /** Interface to Xilinx System Generator Models via PCIe * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel *********************************************************************************/ #include diff --git a/lib/fpga/ips/rtds_axis.c b/lib/fpga/ips/rtds_axis.c index 4b49dbfa6..db1a6a0e5 100644 --- a/lib/fpga/ips/rtds_axis.c +++ b/lib/fpga/ips/rtds_axis.c @@ -1,7 +1,7 @@ /** Driver for AXI Stream wrapper around RTDS_InterfaceModule (rtds_axis ) * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/lib/fpga/ips/switch.c b/lib/fpga/ips/switch.c index b998c4930..2ba9fcd5c 100644 --- a/lib/fpga/ips/switch.c +++ b/lib/fpga/ips/switch.c @@ -3,7 +3,7 @@ * These functions present a simpler interface to Xilinx' AXI Stream switch driver (XAxis_Switch_*) * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include "list.h" diff --git a/lib/fpga/ips/timer.c b/lib/fpga/ips/timer.c index a8c93a7c6..530d2b32c 100644 --- a/lib/fpga/ips/timer.c +++ b/lib/fpga/ips/timer.c @@ -4,7 +4,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include "config.h" diff --git a/lib/fpga/vlnv.c b/lib/fpga/vlnv.c index e656fea43..07030cc50 100644 --- a/lib/fpga/vlnv.c +++ b/lib/fpga/vlnv.c @@ -1,11 +1,8 @@ /** Vendor, Library, Name, Version (VLNV) tag * - * @file * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. - */ + *********************************************************************************/ #include #include diff --git a/lib/hist.c b/lib/hist.c index 09be9e1f5..c50d94740 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -1,7 +1,7 @@ /** Histogram functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/hooks.c b/lib/hooks.c index 6deae555a..c496dd4e3 100644 --- a/lib/hooks.c +++ b/lib/hooks.c @@ -1,7 +1,7 @@ /** Hook-releated functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/hooks/hooks-internal.c b/lib/hooks/hooks-internal.c index 84858300a..1bc1359da 100644 --- a/lib/hooks/hooks-internal.c +++ b/lib/hooks/hooks-internal.c @@ -1,7 +1,7 @@ /** Internal hook functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include "hooks.h" diff --git a/lib/hooks/hooks-other.c b/lib/hooks/hooks-other.c index c0b365bbf..01e787961 100644 --- a/lib/hooks/hooks-other.c +++ b/lib/hooks/hooks-other.c @@ -1,7 +1,7 @@ /** Other hook funktions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index 4a986f7f1..f193c3d5c 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -1,7 +1,7 @@ /** Statistic-related hook functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include "hooks.h" diff --git a/lib/kernel/if.c b/lib/kernel/if.c index 72ad28c66..750e12534 100644 --- a/lib/kernel/if.c +++ b/lib/kernel/if.c @@ -1,7 +1,7 @@ /** Interface related functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/kernel/kernel.c b/lib/kernel/kernel.c index 648a6a7e5..33de7fcf2 100644 --- a/lib/kernel/kernel.c +++ b/lib/kernel/kernel.c @@ -1,7 +1,7 @@ /** Linux kernel related functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/kernel/nl.c b/lib/kernel/nl.c index 16c2810d2..4eace3d6d 100644 --- a/lib/kernel/nl.c +++ b/lib/kernel/nl.c @@ -3,7 +3,7 @@ * VILLASnode uses libnl3 to talk to the Linux kernel to gather networking related information * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/kernel/pci.c b/lib/kernel/pci.c index b7357d633..20e5ce6bc 100644 --- a/lib/kernel/pci.c +++ b/lib/kernel/pci.c @@ -1,7 +1,7 @@ /** Linux PCI helpers * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/lib/kernel/rt.c b/lib/kernel/rt.c index 53cb0de98..2b7a2cbf5 100644 --- a/lib/kernel/rt.c +++ b/lib/kernel/rt.c @@ -1,7 +1,7 @@ /** Linux specific real-time optimizations * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/kernel/tc.c b/lib/kernel/tc.c index 946f88aa2..4ed4a786a 100644 --- a/lib/kernel/tc.c +++ b/lib/kernel/tc.c @@ -3,7 +3,7 @@ * VILLASnode uses these functions to setup the network emulation feature. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/kernel/vfio.c b/lib/kernel/vfio.c index 097b099e7..5784faf95 100644 --- a/lib/kernel/vfio.c +++ b/lib/kernel/vfio.c @@ -1,7 +1,7 @@ /** Virtual Function IO wrapper around kernel API * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #define _DEFAULT_SOURCE diff --git a/lib/list.c b/lib/list.c index 26208045d..1d938e882 100644 --- a/lib/list.c +++ b/lib/list.c @@ -3,7 +3,7 @@ * Linked lists a used for several data structures in the code. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/log.c b/lib/log.c index 898f6dc26..f0cc010bd 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,7 +1,7 @@ /** Logging and debugging routines * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/memory.c b/lib/memory.c index 22ea485a6..f05b7f81d 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -1,8 +1,8 @@ /** Memory allocators. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #include #include diff --git a/lib/msg.c b/lib/msg.c index 8b73dffaf..006fae1a6 100644 --- a/lib/msg.c +++ b/lib/msg.c @@ -1,7 +1,7 @@ /** Message related functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #ifdef __linux__ diff --git a/lib/node.c b/lib/node.c index 19aec00eb..9cfd52c00 100644 --- a/lib/node.c +++ b/lib/node.c @@ -1,7 +1,7 @@ /** Nodes. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/nodes/cbuilder.c b/lib/nodes/cbuilder.c index 8a30cf222..041a7e2f4 100644 --- a/lib/nodes/cbuilder.c +++ b/lib/nodes/cbuilder.c @@ -1,7 +1,7 @@ /** Node type: Wrapper around RSCAD CBuilder model * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include "node.h" diff --git a/lib/nodes/file.c b/lib/nodes/file.c index 0c0074dfb..bc175aa59 100644 --- a/lib/nodes/file.c +++ b/lib/nodes/file.c @@ -1,7 +1,7 @@ /** Node type: File * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/nodes/fpga.c b/lib/nodes/fpga.c index 8ae9f9c6f..5e99515b8 100644 --- a/lib/nodes/fpga.c +++ b/lib/nodes/fpga.c @@ -1,7 +1,7 @@ /** Node type: VILLASfpga * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel *********************************************************************************/ #include diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index c0ec704cb..1b8f1bc99 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -1,7 +1,7 @@ /** Node type: OMA Next Generation Services Interface 10 (NGSI) (FIWARE context broker) * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC **********************************************************************************/ #include diff --git a/lib/nodes/opal.c b/lib/nodes/opal.c index 71e08a1b0..3d39b29e6 100644 --- a/lib/nodes/opal.c +++ b/lib/nodes/opal.c @@ -3,7 +3,7 @@ * This file implements the opal subtype for nodes. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 3c229c5c5..d4c9a5ae1 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -1,7 +1,7 @@ /** Various socket related functions * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index a0dab122a..179c81f3b 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -1,7 +1,7 @@ /** Node type: Websockets (libwebsockets) * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/path.c b/lib/path.c index 0cd0fd243..30f1c4fd8 100644 --- a/lib/path.c +++ b/lib/path.c @@ -1,7 +1,7 @@ /** Message paths. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/plugin.c b/lib/plugin.c index 41bd9e12a..5bcdc528a 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -1,9 +1,7 @@ /** Loadable / plugin support. * * @author Steffen Vogel - * @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include "plugin.h" diff --git a/lib/pool.c b/lib/pool.c index 5d2bb9a88..eacf30a56 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -1,8 +1,8 @@ /** Memory pool for fixed size objects. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC - */ + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ #include "utils.h" diff --git a/lib/queue.c b/lib/queue.c index 20a7a6710..7862dad4f 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -4,7 +4,7 @@ * http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue * * @author Steffen Vogel - * @copyright 2016 Steffen Vogel + * @copyright 2017 Steffen Vogel * @license BSD 2-Clause License * * All rights reserved. @@ -29,7 +29,7 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + *********************************************************************************/ #include "queue.h" #include "utils.h" diff --git a/lib/sample.c b/lib/sample.c index 1e13c9b74..6b63e4445 100644 --- a/lib/sample.c +++ b/lib/sample.c @@ -1,7 +1,7 @@ /** The internal datastructure for a sample of simulation data. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/timing.c b/lib/timing.c index 5d4b80d4f..cf48b9818 100644 --- a/lib/timing.c +++ b/lib/timing.c @@ -1,7 +1,7 @@ /** Time related functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/utils.c b/lib/utils.c index 18609d5bd..20b6430fe 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1,7 +1,7 @@ /** General purpose helper functions. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/lib/web.c b/lib/web.c index a44da1072..383cc48e3 100644 --- a/lib/web.c +++ b/lib/web.c @@ -2,8 +2,6 @@ * * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential. - * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ #include diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index b3dbeda67..ca7966963 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -1,3 +1,9 @@ +/** A simple example hook function which can be loaded as a plugin. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + #include #include #include diff --git a/plugins/models/simple_circuit.c b/plugins/models/simple_circuit.c index 049b7e8a6..aae8d050c 100644 --- a/plugins/models/simple_circuit.c +++ b/plugins/models/simple_circuit.c @@ -1,7 +1,7 @@ /** This is c-code for CBuilder component for Subsystem 2 * Solver used as in RTDS: Resistive companion (Dommel's algo) * Subsystem 1 is modelled in RSCAD - * + * * % Circuit topology * % * % *** Subsystem 1 (SS1) *** % *** Subsystem 2 (SS2) *** @@ -19,8 +19,10 @@ * % |------------------------------------------%------------------ * % * % - */ - + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ /* Variables declared here may be used as parameters inputs or outputs * The have to match with whats in Subsystem.h */ diff --git a/src/fpga-bench-overruns.c b/src/fpga-bench-overruns.c index c6d1576e4..a8bf968e6 100644 --- a/src/fpga-bench-overruns.c +++ b/src/fpga-bench-overruns.c @@ -1,7 +1,7 @@ /** Benchmarks for VILLASfpga: LAPACK & BLAS * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/src/fpga-bench.c b/src/fpga-bench.c index eaec91e60..207f967c6 100644 --- a/src/fpga-bench.c +++ b/src/fpga-bench.c @@ -1,7 +1,7 @@ /** Benchmarks for VILLASfpga * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/src/fpga-tests.c b/src/fpga-tests.c index 0b182e90e..26a6370bf 100644 --- a/src/fpga-tests.c +++ b/src/fpga-tests.c @@ -1,7 +1,7 @@ /** Test procedures for VILLASfpga * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel *********************************************************************************/ #include diff --git a/src/fpga.c b/src/fpga.c index e4f93c78f..db0f71e69 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -1,7 +1,7 @@ /** VILLASfpga utility for tests and benchmarks * * @author Steffen Vogel - * @copyright 2016, Steffen Vogel + * @copyright 2017, Steffen Vogel **********************************************************************************/ #include diff --git a/src/node.c b/src/node.c index 597b7b6f4..505b2b537 100644 --- a/src/node.c +++ b/src/node.c @@ -1,7 +1,7 @@ /** Main routine. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/src/pipe.c b/src/pipe.c index 292d3f877..59821b41a 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC * * @addtogroup tools Test and debug tools * @{ diff --git a/src/signal.c b/src/signal.c index 934b48ebf..731283ae3 100644 --- a/src/signal.c +++ b/src/signal.c @@ -2,7 +2,7 @@ * * @file * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC * * @addtogroup tools Test and debug tools * @{ diff --git a/src/test.c b/src/test.c index 73a4bdb46..b80f0cf31 100644 --- a/src/test.c +++ b/src/test.c @@ -1,7 +1,7 @@ /** Some basic tests. * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/advio.c b/tests/advio.c index e3a63e6c6..e78100971 100644 --- a/tests/advio.c +++ b/tests/advio.c @@ -1,3 +1,9 @@ +/** Unit tests for advio + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + #include #include diff --git a/tests/hist.c b/tests/hist.c index 79dab8655..f8fd3e187 100644 --- a/tests/hist.c +++ b/tests/hist.c @@ -1,7 +1,7 @@ /** Unit tests for histogram * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/list.c b/tests/list.c index 7270d6e1c..226c5b44d 100644 --- a/tests/list.c +++ b/tests/list.c @@ -1,7 +1,7 @@ /** Unit tests for array-based list * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/memory.c b/tests/memory.c index 69234930d..113d2f2dd 100644 --- a/tests/memory.c +++ b/tests/memory.c @@ -1,7 +1,7 @@ /** Unit tests for memory management * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/pool.c b/tests/pool.c index e871e6041..e672679ea 100644 --- a/tests/pool.c +++ b/tests/pool.c @@ -1,7 +1,7 @@ /** Unit tests for memory pool * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/queue.c b/tests/queue.c index 35bc79b11..d5724c9f9 100644 --- a/tests/queue.c +++ b/tests/queue.c @@ -1,3 +1,9 @@ +/** Unit tests for queue + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + #include #include #include diff --git a/tests/timing.c b/tests/timing.c index 4a3ca3d91..2e9f27522 100644 --- a/tests/timing.c +++ b/tests/timing.c @@ -1,7 +1,7 @@ /** Unit tests for time related utlities * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include diff --git a/tests/utils.c b/tests/utils.c index fe649319b..552099757 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -1,7 +1,7 @@ /** Unit tests for utilities * * @author Steffen Vogel - * @copyright 2016, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ #include From e27f0b699f3eed0dfab1be10a5b993cb45f33b82 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 3 Mar 2017 20:21:33 -0400 Subject: [PATCH 092/211] several fixes for clean compilation --- include/villas/api.h | 2 - include/villas/fpga/card.h | 10 ++- include/villas/fpga/ip.h | 2 +- include/villas/log.h | 2 + include/villas/nodes/fpga.h | 2 + include/villas/plugin.h | 9 ++- lib/Makefile.inc | 2 +- lib/api.c | 14 ++-- lib/apis/Makefile.inc | 2 +- lib/apis/config.c | 8 ++- lib/apis/nodes.c | 5 +- lib/apis/reload.c | 4 +- lib/cfg.c | 6 +- lib/fpga/Makefile.inc | 2 +- lib/fpga/card.c | 20 ++++++ lib/fpga/vlnv.c | 6 ++ lib/hooks/hooks-stats.c | 7 +- lib/kernel/pci.c | 1 + lib/kernel/vfio.c | 7 +- lib/log.c | 5 ++ lib/nodes/fpga.c | 22 ++----- lib/nodes/socket.c | 2 + lib/plugin.c | 23 ++++--- lib/web.c | 10 ++- plugins/hooks/example_hook.c | 2 +- src/fpga-bench-overruns.c | 15 ++--- src/fpga-bench.c | 67 +++++++++---------- src/fpga-tests.c | 121 ++++++++++++++++++----------------- src/fpga.c | 45 +++++++------ src/node.c | 10 ++- src/pipe.c | 20 +++--- src/signal.c | 4 +- src/test.c | 18 ++---- thirdparty/Makefile.inc | 4 +- 34 files changed, 267 insertions(+), 212 deletions(-) diff --git a/include/villas/api.h b/include/villas/api.h index c4a421799..06e6da028 100644 --- a/include/villas/api.h +++ b/include/villas/api.h @@ -21,8 +21,6 @@ struct api_ressource; struct api_buffer; struct api_session; -extern struct list apis; - /** Callback type of command function * * @param[inout] c Command handle diff --git a/include/villas/fpga/card.h b/include/villas/fpga/card.h index 707948640..ecb8cbaa3 100644 --- a/include/villas/fpga/card.h +++ b/include/villas/fpga/card.h @@ -11,6 +11,12 @@ #pragma once +#include + +/* Forward declarations */ +struct fpga_ip; +struct vfio_container; + enum fpga_card_state { FPGA_CARD_STATE_UNKOWN, FPGA_CARD_STATE_RESETTED, @@ -45,8 +51,10 @@ struct fpga_card { int fpga_card_parse(struct fpga_card *c, config_setting_t *cfg); +void fpga_card_dump(struct fpga_card *c); + /** Initialize FPGA card and its IP components. */ -int fpga_card_init(struct fpga_card *c); +int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *vc); int fpga_card_destroy(struct fpga_card *c); diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h index 3f8c6ff77..38069ee49 100644 --- a/include/villas/fpga/ip.h +++ b/include/villas/fpga/ip.h @@ -46,9 +46,9 @@ struct fpga_ip_type { int (*parse)(struct fpga_ip *c); int (*init)(struct fpga_ip *c); + int (*destroy)(struct fpga_ip *c); int (*reset)(struct fpga_ip *c); void (*dump)(struct fpga_ip *c); - void (*destroy)(struct fpga_ip *c); }; struct fpga_ip { diff --git a/include/villas/log.h b/include/villas/log.h index 0cf8b5433..f0fc6a126 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -69,6 +69,8 @@ struct log { /** Initialize log object */ int log_init(struct log *l); +int log_destroy(struct log *l); + /** Destroy log object */ int log_destroy(struct log *l); diff --git a/include/villas/nodes/fpga.h b/include/villas/nodes/fpga.h index aa331c709..89d5c0ed5 100644 --- a/include/villas/nodes/fpga.h +++ b/include/villas/nodes/fpga.h @@ -52,6 +52,8 @@ int fpga_parse(struct node *n, config_setting_t *cfg); /** Parse the 'fpga' section in the configuration file */ int fpga_parse_cards(config_setting_t *cfg); +struct fpga_card * fpga_lookup_card(const char *name); + /** @see node_vtable::print */ char * fpga_print(struct node *n); diff --git a/include/villas/plugin.h b/include/villas/plugin.h index a138527ab..de679fcc4 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -26,7 +26,7 @@ __attribute__((destructor)) static void UNIQUE(__dtor)() { \ extern struct list plugins; -enum plugin_types { +enum plugin_type { PLUGIN_TYPE_HOOK, PLUGIN_TYPE_NODE, PLUGIN_TYPE_API, @@ -44,8 +44,9 @@ struct plugin { char *name; char *description; void *handle; + char *path; - enum plugin_types type; + enum plugin_type type; enum plugin_state state; int (*load)(struct plugin *p); @@ -70,5 +71,7 @@ int plugin_load(struct plugin *p); int plugin_unload(struct plugin *p); +void plugin_dump(enum plugin_type type); + /** Find registered and loaded plugin with given name and type. */ -struct plugin * plugin_lookup(enum plugin_types type, const char *name); \ No newline at end of file +struct plugin * plugin_lookup(enum plugin_type type, const char *name); \ No newline at end of file diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 70b415678..c6d4dbd75 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -6,7 +6,7 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ $(addprefix lib/, sample.c path.c node.c hooks.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ - queue.c memory.c advio.c web.c api.c \ + queue.c memory.c advio.c web.c api.c plugin.c \ ) LIB_CFLAGS = $(CFLAGS) -fPIC diff --git a/lib/api.c b/lib/api.c index 39468d3a5..6e83aaa37 100644 --- a/lib/api.c +++ b/lib/api.c @@ -6,6 +6,7 @@ #include +#include "plugin.h" #include "api.h" #include "log.h" #include "config.h" @@ -67,7 +68,7 @@ int api_session_run_command(struct api_session *s, json_t *req, json_t **resp) { int ret; const char *rstr; - struct api_ressource *res; + struct plugin *p; json_t *args; @@ -79,14 +80,14 @@ int api_session_run_command(struct api_session *s, json_t *req, json_t **resp) "error", "invalid request", "code", -1); - res = list_lookup(&apis, rstr); - if (!res) + p = plugin_lookup(PLUGIN_TYPE_API, rstr); + if (!p) *resp = json_pack("{ s: s, s: d, s: s }", "error", "command not found", "code", -2, "command", rstr); - ret = res->cb(res, args, resp, s); + ret = p->api.cb(&p->api, args, resp, s); if (ret) *resp = json_pack("{ s: s, s: d }", "error", "command failed", @@ -226,6 +227,11 @@ int api_init(struct api *a, struct cfg *cfg) return 0; } +int api_destroy(struct api *a) +{ + return 0; +} + int api_deinit(struct api *a) { list_destroy(&a->sessions, (dtor_cb_t) api_session_destroy, false); diff --git a/lib/apis/Makefile.inc b/lib/apis/Makefile.inc index f249c5bbf..bfe1a1d4f 100644 --- a/lib/apis/Makefile.inc +++ b/lib/apis/Makefile.inc @@ -1 +1 @@ -LIB_SRCS += $(wildcard lib/cmds/*.c) \ No newline at end of file +LIB_SRCS += $(wildcard lib/apis/*.c) \ No newline at end of file diff --git a/lib/apis/config.c b/lib/apis/config.c index a0db95c8d..b9d030178 100644 --- a/lib/apis/config.c +++ b/lib/apis/config.c @@ -6,16 +6,18 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ +#include + #include "api.h" #include "utils.h" #include "plugin.h" -static int api_config(struct api_ressource *h, json_t *args, json_t **resp, struct api_info *i) +static int api_config(struct api_ressource *h, json_t *args, json_t **resp, struct api_session *s) { - if (!i->settings.config) + if (!s->api->cfg->cfg) return -1; - *resp = config_to_json(config_setting_root(i->settings.config)); + *resp = config_to_json(config_root_setting(s->api->cfg->cfg)); return 0; } diff --git a/lib/apis/nodes.c b/lib/apis/nodes.c index 106185586..0ba40760a 100644 --- a/lib/apis/nodes.c +++ b/lib/apis/nodes.c @@ -8,17 +8,18 @@ #include +#include "plugin.h" #include "api.h" #include "node.h" #include "utils.h" extern struct list nodes; -static int api_nodes(struct api_ressource *r, json_t *args, json_t **resp, struct api_info *i) +static int api_nodes(struct api_ressource *r, json_t *args, json_t **resp, struct api_session *s) { json_t *json_nodes = json_array(); - list_foreach(struct node *n, i->nodes) { + list_foreach(struct node *n, &s->api->cfg->nodes) { json_t *json_node = json_pack("{ s: s, s: i, s: i, s: i, s: i }", "name", node_name_short(n), "state", n->state, diff --git a/lib/apis/reload.c b/lib/apis/reload.c index 796ba724a..edabfc681 100644 --- a/lib/apis/reload.c +++ b/lib/apis/reload.c @@ -6,9 +6,11 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ +#include "plugin.h" #include "api.h" -static int api_reload(struct api_ressource *h, json_t *args, json_t **resp, struct api_info *i) +/** @todo not implemented yet */ +static int api_reload(struct api_ressource *h, json_t *args, json_t **resp, struct api_session *s) { return -1; } diff --git a/lib/cfg.c b/lib/cfg.c index 111d3ff93..38321ed8f 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -170,7 +170,11 @@ int cfg_parse(struct cfg *cfg, const char *uri) struct plugin plugin; - plugin_parse(&plugin, cfg_plugin); + ret = plugin_parse(&plugin, cfg_plugin); + if (ret) + cerror(cfg_plugin, "Failed to parse plugin"); + + list_push(&cfg->plugins, &plugin); } } diff --git a/lib/fpga/Makefile.inc b/lib/fpga/Makefile.inc index 01a3188c8..0e7058429 100644 --- a/lib/fpga/Makefile.inc +++ b/lib/fpga/Makefile.inc @@ -5,4 +5,4 @@ ifeq ($(shell pkg-config libxil; echo $$?),0) endif endif --include lib/fpga/ip/Makefile.inc \ No newline at end of file +-include lib/fpga/ips/Makefile.inc \ No newline at end of file diff --git a/lib/fpga/card.c b/lib/fpga/card.c index 44636a73b..8af72cff7 100644 --- a/lib/fpga/card.c +++ b/lib/fpga/card.c @@ -133,6 +133,26 @@ int fpga_card_parse(struct fpga_card *c, config_setting_t *cfg) return 0; } +void fpga_card_dump(struct fpga_card *c) +{ + info("VILLASfpga card:"); + { INDENT + info("Slot: %04x:%02x:%02x.%d", c->vd.pdev->slot.domain, c->vd.pdev->slot.bus, c->vd.pdev->slot.device, c->vd.pdev->slot.function); + info("Vendor ID: %04x", c->vd.pdev->id.vendor); + info("Device ID: %04x", c->vd.pdev->id.device); + info("Class ID: %04x", c->vd.pdev->id.class); + + info("BAR0 mapped at %p", c->map); + + info("IP blocks:"); + list_foreach(struct fpga_ip *i, &c->ips) { INDENT + fpga_ip_dump(i); + } + } + + vfio_dump(c->vd.group->container); +} + int fpga_card_check(struct fpga_card *c) { /* Check FPGA configuration */ diff --git a/lib/fpga/vlnv.c b/lib/fpga/vlnv.c index 07030cc50..5021a9b88 100644 --- a/lib/fpga/vlnv.c +++ b/lib/fpga/vlnv.c @@ -8,6 +8,12 @@ #include #include "fpga/vlnv.h" +#include "fpga/ip.h" + +struct fpga_ip * fpga_vlnv_lookup(struct list *l, struct fpga_vlnv *v) +{ + return (struct fpga_ip *) list_search(l, (cmp_cb_t) fpga_vlnv_cmp, v); +} int fpga_vlnv_cmp(struct fpga_vlnv *a, struct fpga_vlnv *b) { diff --git a/lib/hooks/hooks-stats.c b/lib/hooks/hooks-stats.c index f193c3d5c..313d511e8 100644 --- a/lib/hooks/hooks-stats.c +++ b/lib/hooks/hooks-stats.c @@ -10,8 +10,6 @@ #include "utils.h" #include "timing.h" -extern struct list *hook_nodes; - void hook_stats_header() { #define UNIT(u) "(" YEL(u) ")" @@ -101,11 +99,8 @@ int hook_stats_send(struct path *p, struct hook *h, int when, struct sample *smp case HOOK_PARSE: if (!h->parameter) error("Missing parameter for hook '%s'", h->name); - - if (!hook_nodes) - error("Missing reference to node list for hook '%s", h->name); - private->dest = list_lookup(hook_nodes, h->parameter); + private->dest = list_lookup(NULL, h->parameter); if (!private->dest) error("Invalid destination node '%s' for hook '%s'", h->parameter, h->name); diff --git a/lib/kernel/pci.c b/lib/kernel/pci.c index 20e5ce6bc..1dc164627 100644 --- a/lib/kernel/pci.c +++ b/lib/kernel/pci.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "log.h" diff --git a/lib/kernel/vfio.c b/lib/kernel/vfio.c index 5784faf95..b6751f4cf 100644 --- a/lib/kernel/vfio.c +++ b/lib/kernel/vfio.c @@ -12,6 +12,7 @@ #include #include +#include #include #include "utils.h" @@ -93,13 +94,13 @@ int vfio_group_destroy(struct vfio_group *g) ret = ioctl(g->fd, VFIO_GROUP_UNSET_CONTAINER); if (ret) - return; + return ret; debug(5, "VFIO: released group from container: group=%u", g->index); ret = close(g->fd); if (ret) - return; + return ret; debug(5, "VFIO: closed group: group=%u, fd=%d", g->index, g->fd); @@ -115,7 +116,7 @@ int vfio_dev_destroy(struct vfio_dev *d) ret = close(d->fd); if (ret) - return; + return ret; debug(5, "VFIO: closed device: name=%s, fd=%d", d->name, d->fd); diff --git a/lib/log.c b/lib/log.c index f0cc010bd..22a3b0df6 100644 --- a/lib/log.c +++ b/lib/log.c @@ -116,6 +116,11 @@ int log_init(struct log *l) return 0; } +int log_destroy(struct log *l) +{ + return 0; +} + void log_print(struct log *l, const char *lvl, const char *fmt, ...) { va_list ap; diff --git a/lib/nodes/fpga.c b/lib/nodes/fpga.c index 5e99515b8..7928e99c8 100644 --- a/lib/nodes/fpga.c +++ b/lib/nodes/fpga.c @@ -27,22 +27,7 @@ void fpga_dump(struct fpga *f) { struct fpga_card *c = f->ip->card; - info("VILLASfpga card:"); - { INDENT - info("Slot: %04x:%02x:%02x.%d", c->vd.pdev->slot.domain, c->vd.pdev->slot.bus, c->vd.pdev->slot.device, c->vd.pdev->slot.function); - info("Vendor ID: %04x", c->vd.pdev->id.vendor); - info("Device ID: %04x", c->vd.pdev->id.device); - info("Class ID: %04x", c->vd.pdev->id.class); - - info("BAR0 mapped at %p", c->map); - - info("IP blocks:"); - list_foreach(struct fpga_ip *i, &c->ips) { INDENT - fpga_ip_dump(i); - } - } - - vfio_dump(c->vd.group->container); + fpga_card_dump(c); } int fpga_parse_cards(config_setting_t *cfg) @@ -304,6 +289,11 @@ int fpga_write(struct node *n, struct sample *smps[], unsigned cnt) return -1; } +struct fpga_card * fpga_lookup_card(const char *name) +{ + return (struct fpga_card *) list_lookup(&cards, name); +} + static struct plugin p = { .name = "fpga", .description = "VILLASfpga PCIe card (libxil)", diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index d4c9a5ae1..baf688970 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #ifdef __linux__ #include diff --git a/lib/plugin.c b/lib/plugin.c index 5bcdc528a..8a38e5f04 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -4,14 +4,21 @@ * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC *********************************************************************************/ +#include + #include "plugin.h" +/** Global list of all known plugins */ +struct list plugins; + int plugin_init(struct plugin *p, char *name, char *path) { p->name = strdup(name); p->path = strdup(path); p->state = PLUGIN_STATE_UNLOADED; + + return 0; } int plugin_load(struct plugin *p) @@ -36,7 +43,7 @@ int plugin_unload(struct plugin *p) if (ret) return -1; - p->state = UNLOADED; + p->state = PLUGIN_STATE_UNLOADED; return 0; } @@ -59,17 +66,11 @@ int plugin_parse(struct plugin *p, config_setting_t *cfg) path = config_setting_get_string(cfg); if (!path) cerror(cfg, "Setting 'plugin' must be a string."); - - handle = dlopen(path, RTLD_NOW); - if (!handle) - error("Failed to load plugin %s", dlerror()); - - list_push_back(&cfg->plugins, handle); return 0; } -struct plugin * plugin_lookup(enum plugin_types type, const char *name) +struct plugin * plugin_lookup(enum plugin_type type, const char *name) { list_foreach(struct plugin *l, &plugins) { if (l->type == type && strcmp(l->name, name) == 0) @@ -78,3 +79,9 @@ struct plugin * plugin_lookup(enum plugin_types type, const char *name) return NULL; } + +void plugin_dump(enum plugin_type type) +{ + list_foreach(struct plugin *p, &plugins) + printf(" - %s: %s\n", p->name, p->description); +} diff --git a/lib/web.c b/lib/web.c index 383cc48e3..a08c915e5 100644 --- a/lib/web.c +++ b/lib/web.c @@ -173,10 +173,16 @@ int web_init(struct web *w, struct api *a) return 0; } -int web_deinit(struct web *w) +int web_destroy(struct web *w) { - lws_cancel_service(w->context); lws_context_destroy(w->context); return 0; } + +int web_deinit(struct web *w) +{ + lws_cancel_service(w->context); + + return 0; +} diff --git a/plugins/hooks/example_hook.c b/plugins/hooks/example_hook.c index ca7966963..72a03f1e9 100644 --- a/plugins/hooks/example_hook.c +++ b/plugins/hooks/example_hook.c @@ -22,7 +22,7 @@ static int hook_example(struct path *p, struct hook *h, int when, struct sample static struct plugin p = { .name = "example", .description = "This is just a simple example hook", - .type = LOADABLE_TYPE_HOOK, + .type = PLUGIN_TYPE_HOOK, .hook = { .priority = 99, .history = 0, diff --git a/src/fpga-bench-overruns.c b/src/fpga-bench-overruns.c index a8bf968e6..0f0a53ef5 100644 --- a/src/fpga-bench-overruns.c +++ b/src/fpga-bench-overruns.c @@ -8,7 +8,6 @@ #include #include -#include #include "config.h" @@ -61,13 +60,13 @@ static int lapack_workload(int N, double *A) return 0; } -int fpga_benchmark_overruns(struct fpga *f) +int fpga_benchmark_overruns(struct fpga_card *c) { struct fpga_ip *rtds, *dm; - dm = list_lookup(&f->ips, "dma_1"); - rtds = list_lookup(&f->ips, "rtds_axis_0"); - if (!rtds || !f->intc) + dm = list_lookup(&c->ips, "dma_1"); + rtds = list_lookup(&c->ips, "rtds_axis_0"); + if (!rtds || !c->intc) return -1; int ret; @@ -77,10 +76,10 @@ int fpga_benchmark_overruns(struct fpga *f) info("runs = %u", runs); - switch_connect(f->sw, dm, rtds); - switch_connect(f->sw, rtds, dm); + switch_connect(c->sw, dm, rtds); + switch_connect(c->sw, rtds, dm); - intc_enable(f->intc, (1 << (dm->irq + 1 )), intc_flags); + intc_enable(c->intc, (1 << (dm->irq + 1 )), intc_flags); /* Dump results */ char fn[256]; diff --git a/src/fpga-bench.c b/src/fpga-bench.c index 207f967c6..c342243f3 100644 --- a/src/fpga-bench.c +++ b/src/fpga-bench.c @@ -11,32 +11,33 @@ #include #include #include -#include -#include -#include -#include +#include +#include + +#include +#include #include "config.h" -int fpga_benchmark_datamover(struct fpga *f); -int fpga_benchmark_jitter(struct fpga *f); -int fpga_benchmark_memcpy(struct fpga *f); -int fpga_benchmark_latency(struct fpga *f); +int fpga_benchmark_datamover(struct fpga_card *c); +int fpga_benchmark_jitter(struct fpga_card *c); +int fpga_benchmark_memcpy(struct fpga_card *c); +int fpga_benchmark_latency(struct fpga_card *c); #if defined(WITH_BLAS) && defined(WITH_LAPACK) -int fpga_benchmark_overruns(struct fpga *f); +int fpga_benchmark_overruns(struct fpga_card *c); #endif int intc_flags = 0; struct utsname uts; -int fpga_benchmarks(int argc, char *argv[], struct fpga *f) +int fpga_benchmarks(int argc, char *argv[], struct fpga_card *c) { int ret; struct bench { const char *name; - int (*func)(struct fpga *f); + int (*func)(struct fpga_card *c); } benchmarks[] = { { "datamover", fpga_benchmark_datamover }, { "jitter", fpga_benchmark_jitter }, @@ -65,7 +66,7 @@ int fpga_benchmarks(int argc, char *argv[], struct fpga *f) if (ret) return -1; -again: ret = bench->func(f); +again: ret = bench->func(c); if (ret) error("Benchmark %s failed", bench->name); @@ -79,19 +80,19 @@ again: ret = bench->func(f); return -1; } -int fpga_benchmark_jitter(struct fpga *f) +int fpga_benchmark_jitter(struct fpga_card *c) { int ret; struct fpga_ip *tmr; - tmr = list_lookup(&f->ips, "timer_0"); - if (!tmr || !f->intc) + tmr = list_lookup(&c->ips, "timer_0"); + if (!tmr || !c->intc) return -1; XTmrCtr *xtmr = &tmr->timer.inst; - ret = intc_enable(f->intc, (1 << tmr->irq), intc_flags); + ret = intc_enable(c->intc, (1 << tmr->irq), intc_flags); if (ret) error("Failed to enable interrupt"); @@ -106,12 +107,12 @@ int fpga_benchmark_jitter(struct fpga *f) uint64_t end, start = rdtsc(); for (int i = 0; i < runs; i++) { - uint64_t cnt = intc_wait(f->intc, tmr->irq); + uint64_t cnt = intc_wait(c->intc, tmr->irq); if (cnt != 1) warn("fail"); /* Ackowledge IRQ */ - XTmrCtr_WriteReg((uintptr_t) f->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET, XTmrCtr_ReadReg((uintptr_t) f->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET)); + XTmrCtr_WriteReg((uintptr_t) c->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET, XTmrCtr_ReadReg((uintptr_t) c->map + tmr->baseaddr, 0, XTC_TCSR_OFFSET)); end = rdtsc(); hist[i] = end - start; @@ -129,34 +130,34 @@ int fpga_benchmark_jitter(struct fpga *f) free(hist); - ret = intc_disable(f->intc, (1 << tmr->irq)); + ret = intc_disable(c->intc, (1 << tmr->irq)); if (ret) error("Failed to disable interrupt"); return 0; } -int fpga_benchmark_latency(struct fpga *f) +int fpga_benchmark_latency(struct fpga_card *c) { int ret; uint64_t start, end; - if (!f->intc) + if (!c->intc) return -1; int runs = 1000000; int hist[runs]; - ret = intc_enable(f->intc, 0x100, intc_flags); + ret = intc_enable(c->intc, 0x100, intc_flags); if (ret) error("Failed to enable interrupts"); for (int i = 0; i < runs; i++) { start = rdtsc(); - XIntc_Out32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET, 0x100); + XIntc_Out32((uintptr_t) c->map + c->intc->baseaddr + XIN_ISR_OFFSET, 0x100); - intc_wait(f->intc, 8); + intc_wait(c->intc, 8); end = rdtsc(); hist[i] = end - start; @@ -169,14 +170,14 @@ int fpga_benchmark_latency(struct fpga *f) fprintf(g, "%u\n", hist[i]); fclose(g); - ret = intc_disable(f->intc, 0x100); + ret = intc_disable(c->intc, 0x100); if (ret) error("Failed to disable interrupt"); return 0; } -int fpga_benchmark_datamover(struct fpga *f) +int fpga_benchmark_datamover(struct fpga_card *c) { int ret; @@ -191,15 +192,15 @@ int fpga_benchmark_datamover(struct fpga *f) char *dm_name = "dma_1"; #endif - dm = list_lookup(&f->ips, dm_name); + dm = list_lookup(&c->ips, dm_name); if (!dm) error("Unknown datamover"); - ret = switch_connect(f->sw, dm, dm); + ret = switch_connect(c->sw, dm, dm); if (ret) error("Failed to configure switch"); - ret = intc_enable(f->intc, (1 << dm->irq) | (1 << (dm->irq + 1)), intc_flags); + ret = intc_enable(c->intc, (1 << dm->irq) | (1 << (dm->irq + 1)), intc_flags); if (ret) error("Failed to enable interrupt"); @@ -266,7 +267,7 @@ int fpga_benchmark_datamover(struct fpga *f) fclose(g); - ret = switch_disconnect(f->sw, dm, dm); + ret = switch_disconnect(c->sw, dm, dm); if (ret) error("Failed to configure switch"); @@ -274,7 +275,7 @@ int fpga_benchmark_datamover(struct fpga *f) if (ret) error("Failed to release DMA memory"); - ret = intc_disable(f->intc, (1 << dm->irq) | (1 << (dm->irq + 1))); + ret = intc_disable(c->intc, (1 << dm->irq) | (1 << (dm->irq + 1))); if (ret) error("Failed to enable interrupt"); @@ -282,9 +283,9 @@ int fpga_benchmark_datamover(struct fpga *f) return 0; } -int fpga_benchmark_memcpy(struct fpga *f) +int fpga_benchmark_memcpy(struct fpga_card *c) { - char *map = f->map + 0x200000; + char *map = c->map + 0x200000; uint32_t *mapi = (uint32_t *) map; char fn[256]; diff --git a/src/fpga-tests.c b/src/fpga-tests.c index 26a6370bf..53e928e9a 100644 --- a/src/fpga-tests.c +++ b/src/fpga-tests.c @@ -6,14 +6,15 @@ #include #include - -#include +#include #include #include #include -#include +#include +#include +#include #include "config.h" @@ -22,21 +23,21 @@ #define CPU_HZ 3392389000 /* Forward Declarations */ -int fpga_test_intc(struct fpga *f); -int fpga_test_timer(struct fpga *f); -int fpga_test_fifo(struct fpga *f); -int fpga_test_dma(struct fpga *f); -int fpga_test_xsg(struct fpga *f); -int fpga_test_hls_dft(struct fpga *f); -int fpga_test_rtds_rtt(struct fpga *f); +int fpga_test_intc(struct fpga_card *c); +int fpga_test_timer(struct fpga_card *c); +int fpga_test_fifo(struct fpga_card *c); +int fpga_test_dma(struct fpga_card *c); +int fpga_test_xsg(struct fpga_card *c); +int fpga_test_hls_dft(struct fpga_card *c); +int fpga_test_rtds_rtt(struct fpga_card *c); -int fpga_tests(int argc, char *argv[], struct fpga *f) +int fpga_tests(int argc, char *argv[], struct fpga_card *c) { int ret; struct { const char *name; - int (*func)(struct fpga *f); + int (*func)(struct fpga_card *c); } tests[] = { { "Interrupt Controller", fpga_test_intc }, { "Timer Counter", fpga_test_timer }, @@ -48,7 +49,7 @@ int fpga_tests(int argc, char *argv[], struct fpga *f) }; for (int i = 0; i < ARRAY_LEN(tests); i++) { - ret = tests[i].func(f); + ret = tests[i].func(c); info("%s: %s", tests[i].name, (ret == 0) ? GRN("passed") : RED("failed")); } @@ -56,36 +57,36 @@ int fpga_tests(int argc, char *argv[], struct fpga *f) return 0; } -int fpga_test_intc(struct fpga *f) +int fpga_test_intc(struct fpga_card *c) { int ret; uint32_t isr; - if (!f->intc) + if (!c->intc) return -1; - ret = intc_enable(f->intc, 0xFF00, 0); + ret = intc_enable(c->intc, 0xFF00, 0); if (ret) error("Failed to enable interrupt"); /* Fake IRQs in software by writing to ISR */ - XIntc_Out32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00); + XIntc_Out32((uintptr_t) c->map + c->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00); /* Wait for 8 SW triggered IRQs */ for (int i = 0; i < 8; i++) - intc_wait(f->intc, i+8); + intc_wait(c->intc, i+8); /* Check ISR if all SW IRQs have been deliverd */ - isr = XIntc_In32((uintptr_t) f->map + f->intc->baseaddr + XIN_ISR_OFFSET); + isr = XIntc_In32((uintptr_t) c->map + c->intc->baseaddr + XIN_ISR_OFFSET); - ret = intc_disable(f->intc, 0xFF00); + ret = intc_disable(c->intc, 0xFF00); if (ret) error("Failed to disable interrupt"); return (isr & 0xFF00) ? -1 : 0; /* ISR should get cleared by MSI_Grant_signal */ } -int fpga_test_xsg(struct fpga *f) +int fpga_test_xsg(struct fpga_card *c) { int ret; double factor, err = 0; @@ -94,8 +95,8 @@ int fpga_test_xsg(struct fpga *f) struct model_param *p; struct dma_mem mem; - xsg = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { NULL, "sysgen", "xsg_multiply", NULL }); - dma = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL }); + xsg = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { NULL, "sysgen", "xsg_multiply", NULL }); + dma = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL }); /* Check if required IP is available on FPGA */ if (!dma || !xsg || !dma) @@ -111,10 +112,10 @@ int fpga_test_xsg(struct fpga *f) info("Model param: factor = %f", factor); - ret = switch_connect(f->sw, dma, xsg); + ret = switch_connect(c->sw, dma, xsg); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, xsg, dma); + ret = switch_connect(c->sw, xsg, dma); if (ret) error("Failed to configure switch"); @@ -137,10 +138,10 @@ int fpga_test_xsg(struct fpga *f) info("Error after FPGA operation: err = %f", err); - ret = switch_disconnect(f->sw, dma, xsg); + ret = switch_disconnect(c->sw, dma, xsg); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, xsg, dma); + ret = switch_disconnect(c->sw, xsg, dma); if (ret) error("Failed to configure switch"); @@ -151,26 +152,26 @@ int fpga_test_xsg(struct fpga *f) return err > 1e-3; } -int fpga_test_hls_dft(struct fpga *f) +int fpga_test_hls_dft(struct fpga_card *c) { int ret; struct fpga_ip *hls, *rtds; - rtds = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); - hls = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { NULL, "hls", "hls_dft", NULL }); + rtds = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); + hls = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { NULL, "hls", "hls_dft", NULL }); /* Check if required IP is available on FPGA */ if (!hls || !rtds) return -1; - ret = intc_enable(f->intc, (1 << rtds->irq), 0); + ret = intc_enable(c->intc, (1 << rtds->irq), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, rtds, hls); + ret = switch_connect(c->sw, rtds, hls); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, hls, rtds); + ret = switch_connect(c->sw, hls, rtds); if (ret) error("Failed to configure switch"); @@ -195,32 +196,32 @@ int fpga_test_hls_dft(struct fpga *f) } #endif - ret = switch_disconnect(f->sw, rtds, hls); + ret = switch_disconnect(c->sw, rtds, hls); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, hls, rtds); + ret = switch_disconnect(c->sw, hls, rtds); if (ret) error("Failed to configure switch"); return 0; } -int fpga_test_fifo(struct fpga *f) +int fpga_test_fifo(struct fpga_card *c) { int ret; ssize_t len; char src[255], dst[255]; struct fpga_ip *fifo; - fifo = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }); + fifo = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_fifo_mm_s", NULL }); if (!fifo) return -1; - ret = intc_enable(f->intc, (1 << fifo->irq), 0); + ret = intc_enable(c->intc, (1 << fifo->irq), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, fifo, fifo); + ret = switch_connect(c->sw, fifo, fifo); if (ret) error("Failed to configure switch"); @@ -238,11 +239,11 @@ int fpga_test_fifo(struct fpga *f) if (len != sizeof(dst)) error("Failed to read from FIFO"); - ret = intc_disable(f->intc, (1 << fifo->irq)); + ret = intc_disable(c->intc, (1 << fifo->irq)); if (ret) error("Failed to disable interrupt"); - ret = switch_disconnect(f->sw, fifo, fifo); + ret = switch_disconnect(c->sw, fifo, fifo); if (ret) error("Failed to configure switch"); @@ -250,13 +251,13 @@ int fpga_test_fifo(struct fpga *f) return memcmp(src, dst, sizeof(src)); } -int fpga_test_dma(struct fpga *f) +int fpga_test_dma(struct fpga_card *c) { int ret = -1; struct dma_mem mem, src, dst; - list_foreach(struct fpga_ip *dma, &f->ips) { INDENT - if (!fpga_vlnv_match(dma, "xilinx.com", "ip", "axi_dma", NULL)) + list_foreach(struct fpga_ip *dma, &c->ips) { INDENT + if (!fpga_vlnv_cmp(&dma->vlnv, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL })) continue; /* skip non DMA IP cores */ /* Simple DMA can only transfer up to 4 kb due to @@ -279,11 +280,11 @@ int fpga_test_dma(struct fpga *f) int irq_mm2s = dma->irq; int irq_s2mm = dma->irq + 1; - ret = intc_enable(f->intc, (1 << irq_mm2s) | (1 << irq_s2mm), 0); + ret = intc_enable(c->intc, (1 << irq_mm2s) | (1 << irq_s2mm), 0); if (ret) error("Failed to enable interrupt"); - ret = switch_connect(f->sw, dma, dma); + ret = switch_connect(c->sw, dma, dma); if (ret) error("Failed to configure switch"); @@ -296,11 +297,11 @@ int fpga_test_dma(struct fpga *f) info("DMA %s (%s): %s", dma->name, dma->dma.inst.HasSg ? "scatter-gather" : "simple", ret ? RED("failed") : GRN("passed")); - ret = switch_disconnect(f->sw, dma, dma); + ret = switch_disconnect(c->sw, dma, dma); if (ret) error("Failed to configure switch"); - ret = intc_disable(f->intc, (1 << irq_mm2s) | (1 << irq_s2mm)); + ret = intc_disable(c->intc, (1 << irq_mm2s) | (1 << irq_s2mm)); if (ret) error("Failed to disable interrupt"); @@ -312,18 +313,18 @@ int fpga_test_dma(struct fpga *f) return ret; } -int fpga_test_timer(struct fpga *f) +int fpga_test_timer(struct fpga_card *c) { int ret; struct fpga_ip *tmr; - tmr = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_timer", NULL }); + tmr = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_timer", NULL }); if (!tmr) return -1; XTmrCtr *xtmr = &tmr->timer.inst; - ret = intc_enable(f->intc, (1 << tmr->irq), 0); + ret = intc_enable(c->intc, (1 << tmr->irq), 0); if (ret) error("Failed to enable interrupt"); @@ -331,7 +332,7 @@ int fpga_test_timer(struct fpga *f) XTmrCtr_SetResetValue(xtmr, 0, FPGA_AXI_HZ / 125); XTmrCtr_Start(xtmr, 0); - uint64_t counter = intc_wait(f->intc, tmr->irq); + uint64_t counter = intc_wait(c->intc, tmr->irq); info("Got IRQ: counter = %ju", counter); if (counter == 1) @@ -339,14 +340,14 @@ int fpga_test_timer(struct fpga *f) else warn("Counter was not 1"); - intc_disable(f->intc, (1 << tmr->irq)); + intc_disable(c->intc, (1 << tmr->irq)); if (ret) error("Failed to disable interrupt"); return -1; } -int fpga_test_rtds_rtt(struct fpga *f) +int fpga_test_rtds_rtt(struct fpga_card *c) { int ret; struct fpga_ip *dma, *rtds; @@ -354,17 +355,17 @@ int fpga_test_rtds_rtt(struct fpga *f) size_t recvlen; /* Get IP cores */ - rtds = fpga_vlnv_lookup(&f->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); - dma = list_lookup(&f->ips, "dma_1"); + rtds = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL }); + dma = list_lookup(&c->ips, "dma_1"); /* Check if required IP is available on FPGA */ if (!dma || !rtds) return -1; - ret = switch_connect(f->sw, rtds, dma); + ret = switch_connect(c->sw, rtds, dma); if (ret) error("Failed to configure switch"); - ret = switch_connect(f->sw, dma, rtds); + ret = switch_connect(c->sw, dma, rtds); if (ret) error("Failed to configure switch"); @@ -391,10 +392,10 @@ int fpga_test_rtds_rtt(struct fpga *f) error("Failed to complete DMA write: %d", ret); } - ret = switch_disconnect(f->sw, rtds, dma); + ret = switch_disconnect(c->sw, rtds, dma); if (ret) error("Failed to configure switch"); - ret = switch_disconnect(f->sw, dma, rtds); + ret = switch_disconnect(c->sw, dma, rtds); if (ret) error("Failed to configure switch"); diff --git a/src/fpga.c b/src/fpga.c index db0f71e69..166939b29 100644 --- a/src/fpga.c +++ b/src/fpga.c @@ -18,17 +18,19 @@ #include #include +#include + #include "config.h" /* Declarations */ -int fpga_benchmarks(int argc, char *argv[], struct fpga *f); -int fpga_tests(int argc, char *argv[], struct fpga *f); +int fpga_benchmarks(int argc, char *argv[], struct fpga_card *c); +int fpga_tests(int argc, char *argv[], struct fpga_card *c); -struct cfg settings; +struct cfg cfg; void usage(char *name) { - printf("Usage: %s CONFIGFILE CMD [OPTIONS]\n", name); + printf("Usage: %s CONFIGFILE CARD CMD [OPTIONS]\n", name); printf(" Commands:\n"); printf(" tests Test functionality of VILLASfpga card\n"); printf(" benchmarks Do benchmarks\n\n"); @@ -43,19 +45,18 @@ void usage(char *name) int main(int argc, char *argv[]) { int ret; - struct fpga *fpga; - config_t config; + struct fpga_card *card; enum { FPGA_TESTS, FPGA_BENCH } subcommand; - if (argc < 3) + if (argc < 4) usage(argv[0]); - if (strcmp(argv[2], "tests") == 0) + if (strcmp(argv[3], "tests") == 0) subcommand = FPGA_TESTS; - else if (strcmp(argv[2], "benchmarks") == 0) + else if (strcmp(argv[3], "benchmarks") == 0) subcommand = FPGA_BENCH; else usage(argv[0]); @@ -65,7 +66,7 @@ int main(int argc, char *argv[]) while ((c = getopt(argc-1, argv+1, "d:")) != -1) { switch (c) { case 'd': - log_setlevel(strtoul(optarg, &endptr, 10), ~0); + cfg.log.level = strtoul(optarg, &endptr, 10); break; case '?': @@ -75,32 +76,34 @@ int main(int argc, char *argv[]) } info("Parsing configuration"); - cfg_parse(argv[1], &config, &settings, NULL, NULL); + cfg_parse(&cfg, argv[1]); info("Initialize real-time system"); - rt_init(settings.affinity, settings.priority); + rt_init(&cfg); /* Initialize VILLASfpga card */ - config_setting_t *cfg_root = config_root_setting(&config); - ret = fpga_init(argc, argv, cfg_root); + ret = fpga_init(argc, argv, config_root_setting(cfg.cfg)); if (ret) error("Failed to initialize FPGA card"); - fpga = fpga_get(); - fpga_dump(fpga); + card = fpga_lookup_card(argv[2]); + if (!card) + error("FPGA card '%s' does not exist", argv[2]); + + fpga_card_dump(card); /* Start subcommand */ switch (subcommand) { - case FPGA_TESTS: fpga_tests(argc-optind-1, argv+optind+1, fpga); break; - case FPGA_BENCH: fpga_benchmarks(argc-optind-1, argv+optind+1, fpga); break; + case FPGA_TESTS: fpga_tests(argc-optind-1, argv+optind+1, card); break; + case FPGA_BENCH: fpga_benchmarks(argc-optind-1, argv+optind+1, card); break; } /* Shutdown */ - ret = fpga_deinit(&fpga); + ret = fpga_deinit(); if (ret) - error("Failed to de-initialize fpga card"); + error("Failed to de-initialize FPGA card"); - cfg_destroy(&config); + cfg_destroy(&cfg); return 0; } diff --git a/src/node.c b/src/node.c index 505b2b537..98c673fd5 100644 --- a/src/node.c +++ b/src/node.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -74,18 +75,15 @@ static void usage(const char *name) printf(" See in the RT-LAB User Guide for more information.\n\n"); #endif printf("Supported node types:\n"); - list_foreach(struct node_type *vt, &node_types) - printf(" - %s: %s\n", vt->name, vt->description); + plugin_dump(PLUGIN_TYPE_NODE); printf("\n"); printf("Supported hooks:\n"); - list_foreach(struct hook *h, &hooks) - printf(" - %s: %s\n", h->name, h->description); + plugin_dump(PLUGIN_TYPE_HOOK); printf("\n"); printf("Supported API commands:\n"); - list_foreach(struct api_ressource *r, &apis) - printf(" - %s: %s\n", r->name, r->description); + plugin_dump(PLUGIN_TYPE_API); printf("\n"); print_copyright(); diff --git a/src/pipe.c b/src/pipe.c index 59821b41a..287796e6f 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -24,9 +24,8 @@ #include "config.h" -static struct list nodes; /**< List of all nodes */ -static struct cfg settings; /**< The global configuration */ -static config_t config; +static struct list nodes; /**< List of all nodes */ +static struct cfg cfg; /**< The global configuration */ struct dir { struct pool pool; @@ -59,8 +58,7 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) node_stop(node); node_deinit(node->_vt); - list_destroy(&nodes, (dtor_cb_t) node_destroy, false); - cfg_destroy(&config); + cfg_destroy(&cfg); info(GRN("Goodbye!")); exit(EXIT_SUCCESS); @@ -173,7 +171,7 @@ int main(int argc, char *argv[]) char c; ptid = pthread_self(); - log_init(); + log_init(&cfg.log); /* Parse command line arguments */ if (argc < 3) @@ -195,7 +193,7 @@ int main(int argc, char *argv[]) sendd.enabled = false; // receive only break; case 'd': - log_setlevel(atoi(optarg), -1); + cfg.log.level = atoi(optarg); break; case 'h': case '?': @@ -214,13 +212,11 @@ int main(int argc, char *argv[]) sigaction(SIGINT, &sa_quit, NULL); /* Initialize log, configuration.. */ - list_init(&nodes); - info("Parsing configuration"); - cfg_parse(argv[1], &config, &settings, &nodes, NULL); + cfg_parse(&cfg, argv[1]); info("Initialize real-time system"); - rt_init(settings.affinity, settings.priority); + rt_init(&cfg); /* Initialize node */ node = list_lookup(&nodes, argv[2]); @@ -230,7 +226,7 @@ int main(int argc, char *argv[]) if (reverse) node_reverse(node); - ret = node_init(node->_vt, argc-optind, argv+optind, config_root_setting(&config)); + ret = node_init(node->_vt, argc-optind, argv+optind, config_root_setting(cfg.cfg)); if (ret) error("Failed to intialize node: %s", node_name(node)); diff --git a/src/signal.c b/src/signal.c index 731283ae3..c61d16f66 100644 --- a/src/signal.c +++ b/src/signal.c @@ -44,6 +44,8 @@ void usage(char *name) int main(int argc, char *argv[]) { + struct log log; + /* Some default values */ double rate = 10; double freq = 1; @@ -54,7 +56,7 @@ int main(int argc, char *argv[]) int limit = -1; int counter; - log_init(); + log_init(&log); if (argc < 2) { usage(argv[0]); diff --git a/src/test.c b/src/test.c index b80f0cf31..01367f0b7 100644 --- a/src/test.c +++ b/src/test.c @@ -20,8 +20,7 @@ #include "timing.h" #include "pool.h" -struct cfg settings; /** _vt, argc-3, argv+3, config_root_setting(&config)); + node_init(node->_vt, argc-3, argv+3, config_root_setting(cfg.cfg)); node_start(node); /* Parse Arguments */ @@ -137,8 +132,7 @@ check: if (optarg == endptr) node_stop(node); node_deinit(node->_vt); - list_destroy(&nodes, (dtor_cb_t) node_destroy, false); - cfg_destroy(&config); + cfg_destroy(&cfg); return 0; } diff --git a/thirdparty/Makefile.inc b/thirdparty/Makefile.inc index 7fc108858..a909dd938 100644 --- a/thirdparty/Makefile.inc +++ b/thirdparty/Makefile.inc @@ -24,9 +24,9 @@ $(addprefix install-,$(DEPS)): install-%: % $(addprefix clean-,$(DEPS)): rm -rf $(BUILDDIR)/thirdparty/$(@:clean-%=%) -install-thirdparty: +install-thirdparty: $(addprefix install-,$(DEPS)) -clean-thirdparty: +clean-thirdparty: $(addprefix clean-,$(DEPS)) rm -rf $(BUILDDIR)/thirdparty .PHONY: $(DEPS) thirdparty clean-thirdparty install-thirdparty From 3c890b6e882eb529cfb16f430b54c0d5d76a8028 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 5 Mar 2017 10:47:26 -0400 Subject: [PATCH 093/211] added new -n option to villas-signal in order to generate unthrottled / non real-time output of samples --- src/signal.c | 61 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/src/signal.c b/src/signal.c index 08ab41a40..d4cdc285b 100644 --- a/src/signal.c +++ b/src/signal.c @@ -35,6 +35,7 @@ void usage() printf(" SIGNAL is on of: 'mixed', 'random', 'sine', 'triangle', 'square', 'ramp'\n"); printf(" -v NUM specifies how many values a message should contain\n"); printf(" -r HZ how many messages per second\n"); + printf(" -n non real-time mode. do not throttle output.\n"); printf(" -f HZ the frequency of the signal\n"); printf(" -a FLT the amplitude\n"); printf(" -d FLT the standard deviation for 'random' signals\n"); @@ -46,17 +47,24 @@ void usage() int main(int argc, char *argv[]) { struct log log; + struct timespec start, now; + enum { + MODE_RT, + MODE_NON_RT + } mode = MODE_RT; + /* Some default values */ double rate = 10; double freq = 1; double ampl = 1; double stddev = 0.02; + double running; int type = TYPE_MIXED; int values = 1; int limit = -1; - int counter; - + int counter, tfd, steps; + log_init(&log, V, LOG_ALL); if (argc < 2) { @@ -80,7 +88,7 @@ int main(int argc, char *argv[]) /* Parse optional command line arguments */ char c, *endptr; - while ((c = getopt(argc-1, argv+1, "hv:r:f:l:a:d:")) != -1) { + while ((c = getopt(argc-1, argv+1, "hv:r:f:l:a:d:n")) != -1) { switch (c) { case 'l': limit = strtoul(optarg, &endptr, 10); @@ -100,6 +108,9 @@ int main(int argc, char *argv[]) case 'd': stddev = strtof(optarg, &endptr); goto check; + case 'n': + mode = MODE_NON_RT; + break; case 'h': case '?': usage(); @@ -121,16 +132,28 @@ check: if (optarg == endptr) printf("# %-20s\t\t%s\n", "sec.nsec(seq)", "data[]"); /* Setup timer */ - int tfd = timerfd_create_rate(rate); - if (tfd < 0) - serror("Failed to create timer"); + if (mode == MODE_RT) { + tfd = timerfd_create_rate(rate); + if (tfd < 0) + serror("Failed to create timer"); + } - struct timespec start = time_now(); + start = time_now(); counter = 0; while (limit < 0 || counter < limit) { - struct timespec now = time_now(); - double running = time_delta(&start, &now); + if (mode == MODE_RT) { + now = time_now(); + running = time_delta(&start, &now); + } + else { + struct timespec offset; + + running = counter * 1.0 / rate; + offset = time_from_double(running); + + now = time_add(&start, &offset); + } s->ts.origin = now; s->sequence = counter; @@ -150,16 +173,22 @@ check: if (optarg == endptr) sample_fprint(stdout, s, SAMPLE_ALL & ~SAMPLE_OFFSET); fflush(stdout); - /* Block until 1/p->rate seconds elapsed */ - int steps = timerfd_wait(tfd); - - if (steps > 1) - warn("Missed steps: %u", steps); + /* Throttle output if desired */ + if (mode == MODE_RT) { + /* Block until 1/p->rate seconds elapsed */ + steps = timerfd_wait(tfd); + if (steps > 1) + warn("Missed steps: %u", steps); - counter += steps; + counter += steps; + } + else + counter += 1; } - close(tfd); + if (mode == MODE_RT) + close(tfd); + free(s); return 0; From 1510da9baeab6100d87a7c0ae54ae756db8329e4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 5 Mar 2017 11:04:07 -0400 Subject: [PATCH 094/211] improved debug output of memory initialisation --- lib/memory.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/memory.c b/lib/memory.c index 0a2075745..eb9cf0d4e 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -18,14 +18,14 @@ #include "memory.h" int memory_init() -{ +{ INDENT #ifdef __linux__ int nr = kernel_get_nr_hugepages(); - debug(LOG_MEM | 2, "System has %d reserved hugepages", nr); - - if (nr < DEFAULT_NR_HUGEPAGES) + if (nr < DEFAULT_NR_HUGEPAGES) { kernel_set_nr_hugepages(DEFAULT_NR_HUGEPAGES); + debug(LOG_MEM | 2, "Reserve %d hugepages (was %d)", DEFAULT_NR_HUGEPAGES, nr); + } #endif return 0; } From 4e9c04755e9288e7db618c6bb3c733c5bc420e22 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 5 Mar 2017 11:09:37 -0400 Subject: [PATCH 095/211] fix listing of supported plugins (hooks, api, node types) --- lib/plugin.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/plugin.c b/lib/plugin.c index 8a38e5f04..556e7e378 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -82,6 +82,8 @@ struct plugin * plugin_lookup(enum plugin_type type, const char *name) void plugin_dump(enum plugin_type type) { - list_foreach(struct plugin *p, &plugins) - printf(" - %s: %s\n", p->name, p->description); + list_foreach(struct plugin *p, &plugins) { + if (p->type == type) + printf(" - %-12s: %s\n", p->name, p->description); + } } From fa648d5cac3abf984eaef54783f11071aa967148 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 5 Mar 2017 11:10:10 -0400 Subject: [PATCH 096/211] =?UTF-8?q?add=20=E2=80=94-help=20/=20-h=20option?= =?UTF-8?q?=20to=20villas-node?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/node.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/node.c b/src/node.c index 69d95e826..888a16c49 100644 --- a/src/node.c +++ b/src/node.c @@ -97,8 +97,13 @@ int main(int argc, char *argv[]) char *uri = "opal-shmem.conf"; #else - if (argc > 2) - usage(argv[0]); + if (argc == 2) { + if (!strcmp(argv[1], "-h") || + !strcmp(argv[1], "--help")) + usage(); + } + else if (argc > 2) + usage(); char *uri = (argc == 2) ? argv[1] : NULL; #endif From 10bdf4db51d50696fa8c9b402005edf386963d02 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 6 Mar 2017 08:57:43 -0400 Subject: [PATCH 097/211] properly use ne plugin system to find node-types --- lib/cfg.c | 23 ++++++++++++++++------- lib/node.c | 14 +++++++------- src/node.c | 7 ------- src/pipe.c | 3 +-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/cfg.c b/lib/cfg.c index a556cb4db..6d4eafae5 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -52,14 +52,22 @@ int cfg_init_post(struct cfg *cfg) info("Initialize web sub-system"); web_init(&cfg->web, &cfg->api); + info("Initialize node types"); + list_foreach(struct node *n, &cfg->nodes) { INDENT + config_setting_t *cfg_root = config_root_setting(&cfg->cfg); + + node_type_init(n->_vt, cfg->cli.argc, cfg->cli.argv, cfg_root); + } + return 0; } int cfg_deinit(struct cfg *cfg) { info("De-initializing node types"); - list_foreach(struct node_type *vt, &node_types) { INDENT - node_deinit(vt); + list_foreach(struct plugin *p, &plugins) { INDENT + if (p->type == PLUGIN_TYPE_NODE) + node_type_deinit(&p->node); } info("De-initializing web interface"); @@ -201,19 +209,20 @@ int cfg_parse(struct cfg *cfg, const char *uri) for (int i = 0; i < config_setting_length(cfg_nodes); i++) { config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i); - - struct node_type *vt; + + struct plugin *p; const char *type; /* Required settings */ if (!config_setting_lookup_string(cfg_node, "type", &type)) cerror(cfg_node, "Missing node type"); - vt = list_lookup(&node_types, type); - if (!vt) + + p = plugin_lookup(PLUGIN_TYPE_NODE, type); + if (!p) cerror(cfg_node, "Invalid node type: %s", type); - struct node *n = node_create(vt); + struct node *n = node_create(&p->node); ret = node_parse(n, cfg_node); if (ret) diff --git a/lib/node.c b/lib/node.c index dc5661bb6..f4fd8f9fd 100644 --- a/lib/node.c +++ b/lib/node.c @@ -13,9 +13,7 @@ #include "cfg.h" #include "utils.h" #include "config.h" - -/** List of registered node-types */ -struct list node_types = LIST_INIT(); +#include "plugin.h" int node_read(struct node *n, struct sample *smps[], unsigned cnt) { @@ -262,7 +260,7 @@ int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all) int node_parse(struct node *n, config_setting_t *cfg) { - struct node_type *vt; + struct plugin *p; const char *type, *name; int ret; @@ -271,9 +269,11 @@ int node_parse(struct node *n, config_setting_t *cfg) if (!config_setting_lookup_string(cfg, "type", &type)) cerror(cfg, "Missing node type"); - vt = list_lookup(&node_types, type); - if (!vt) - cerror(cfg, "Invalid type for node '%s'", config_setting_name(cfg)); + p = plugin_lookup(PLUGIN_TYPE_NODE, type); + assert(&p->node == n->_vt); + + if (!config_setting_lookup_int(cfg, "vectorize", &n->vectorize)) + n->vectorize = 1; n->name = name; n->cfg = cfg; diff --git a/src/node.c b/src/node.c index 888a16c49..c73069b7e 100644 --- a/src/node.c +++ b/src/node.c @@ -127,13 +127,6 @@ int main(int argc, char *argv[]) cfg_init_post(&cfg); - info("Initialize node types"); - list_foreach(struct node_type *vt, &node_types) { INDENT - int refs = list_length(&vt->instances); - if (refs > 0) - node_init(vt, argc, argv, config_root_setting(&cfg.cfg)); - } - info("Starting nodes"); list_foreach(struct node *n, &cfg.nodes) { INDENT int refs = list_count(&cfg.paths, (cmp_cb_t) path_uses_node, n); diff --git a/src/pipe.c b/src/pipe.c index 22211ae89..a92005c77 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -24,7 +24,6 @@ #include "config.h" -static struct list nodes; /**< List of all nodes */ static struct cfg cfg; /**< The global configuration */ struct dir { @@ -223,7 +222,7 @@ int main(int argc, char *argv[]) memory_init(); /* Initialize node */ - node = list_lookup(&nodes, argv[2]); + node = list_lookup(&cfg.nodes, argv[2]); if (!node) error("Node '%s' does not exist!", argv[2]); From 21d6ff20c435269aed43d84495759b481dae733f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 6 Mar 2017 08:58:58 -0400 Subject: [PATCH 098/211] split node and node_type into separate files --- include/villas/node.h | 143 +---------------------------------- include/villas/node_type.h | 150 +++++++++++++++++++++++++++++++++++++ lib/Makefile.inc | 3 +- lib/node.c | 41 ---------- lib/node_type.c | 51 +++++++++++++ src/node.c | 4 +- src/pipe.c | 4 +- src/test.c | 4 +- 8 files changed, 212 insertions(+), 188 deletions(-) create mode 100644 include/villas/node_type.h create mode 100644 lib/node_type.c diff --git a/include/villas/node.h b/include/villas/node.h index f2491e43d..5332fa938 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -14,17 +14,11 @@ #include #include +#include "node_type.h" #include "sample.h" #include "list.h" #include "queue.h" -extern struct list node_types; /**< Vtable for virtual node sub types */ - -/* Forward declarations */ -struct node_type; -struct settings; -typedef struct config_setting_t config_setting_t; - /** The data structure for a node. * * Every entity which exchanges messages is represented by a node. @@ -57,135 +51,6 @@ struct node config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this node */ }; -/** C++ like vtable construct for node_types */ -struct node_type { - const char *name; /**< The unique name of this node. This must be allways the first member! */ - const char *description; /**< A short description of this node type. Will be shown in help text. */ - int vectorize; /**< Maximal vector length supported by this node type. Zero is unlimited. */ - - struct list instances; /**< A list of all existing nodes of this type. */ - size_t size; /**< Size of private data bock. @see node::_vd */ - - enum node_type_state { - NODE_TYPE_UNINITIALIZED = 0, - NODE_TYPE_INITIALIZED - } state; - - /** Global initialization per node type. - * - * This callback is invoked once per node-type. - * - * @param argc Number of arguments passed to the server executable (see main()). - * @param argv Array of arguments passed to the server executable (see main()). - * @param cfg Root libconfig object of global configuration file. - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ - int (*init)(int argc, char * argv[], config_setting_t *cfg); - - /** Global de-initialization per node type. - * - * This callback is invoked once per node-type. - * - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ - int (*deinit)(); - - /** Allocate memory for an instance of this type. - * - * @return A pointer to the node-type specific private data. - */ - void * (*create)(); - - /** Free memory of an instance of this type. - * - * @param n A pointer to the node object. - */ - int (*destroy)(struct node *n); - - /** Parse node connection details.‚ - * - * @param n A pointer to the node object. - * @param cfg A libconfig object pointing to the node. - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ - int (*parse)(struct node *n, config_setting_t *cfg); - - /** Returns a string with a textual represenation of this node. - * - * @param n A pointer to the node object. - * @return A pointer to a dynamically allocated string. Must be freed(). - */ - char * (*print)(struct node *n); - - /** Opens the connection to this node. - * - * @param n A pointer to the node object. - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ - int (*open) (struct node *n); - - /** Close the connection to this node. - * - * @param n A pointer to the node object. - * @retval 0 Success. Everything went well. - * @retval <0 Error. Something went wrong. - */ - int (*close)(struct node *n); - - /** Receive multiple messages at once. - * - * Messages are received with a single recvmsg() syscall by - * using gathering techniques (struct iovec). - * The messages will be stored in a circular buffer / array @p m. - * Indexes used to address @p m will wrap around after len messages. - * Some node types might only support to receive one message at a time. - * - * @param n A pointer to the node object. - * @param smps An array of pointers to memory blocks where the function should store received samples. - * @param cnt The number of messages which should be received. - * @return The number of messages actually received. - */ - int (*read) (struct node *n, struct sample *smps[], unsigned cnt); - - /** Send multiple messages in a single datagram / packet. - * - * Messages are sent with a single sendmsg() syscall by - * using gathering techniques (struct iovec). - * The messages have to be stored in a circular buffer / array m. - * So the indexes will wrap around after len. - * - * @param n A pointer to the node object. - * @param smps An array of pointers to memory blocks where samples read from. - * @param cnt The number of messages which should be sent. - * @return The number of messages actually sent. - */ - int (*write)(struct node *n, struct sample *smps[], unsigned cnt); - - /** Reverse source and destination of a node. - * - * This is not supported by all node types! - * - * @param n A pointer to the node object. - */ - int (*reverse)(struct node *n); -}; - -/** Initialize all registered node type subsystems. - * - * @see node_type::init - */ -int node_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg); - -/** De-initialize node type subsystems. - * - * @see node_type::deinit - */ -int node_deinit(struct node_type *vt); - /** Create a node by allocating dynamic memory. * * @see node_type::create @@ -229,9 +94,6 @@ char * node_name(struct node *n); */ char * node_name_long(struct node *n); -/** Return a pointer to a string which describes the node type */ -const char * node_name_type(struct node *n); - /** Reverse local and remote socket address. * * @see node_type::reverse @@ -263,4 +125,7 @@ int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all); */ int node_parse(struct node *n, config_setting_t *cfg); +/** Validate node configuration. */ +int node_check(struct node *n); + /** @} */ \ No newline at end of file diff --git a/include/villas/node_type.h b/include/villas/node_type.h new file mode 100644 index 000000000..aa57bd4ba --- /dev/null +++ b/include/villas/node_type.h @@ -0,0 +1,150 @@ +/** Nodes + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * + * @addtogroup node Node + * @{ + *********************************************************************************/ + +#pragma once + +#include + +#include "list.h" + +/* Forward declarations */ +struct node; +struct sample; + +/** C++ like vtable construct for node_types */ +struct node_type { + const char *name; /**< The unique name of this node. This must be allways the first member! */ + const char *description; /**< A short description of this node type. Will be shown in help text. */ + int vectorize; /**< Maximal vector length supported by this node type. Zero is unlimited. */ + + struct list instances; /**< A list of all existing nodes of this type. */ + size_t size; /**< Size of private data bock. @see node::_vd */ + + enum node_type_state { + NODE_TYPE_UNINITIALIZED = 0, + NODE_TYPE_INITIALIZED + } state; + + /** Global initialization per node type. + * + * This callback is invoked once per node-type. + * + * @param argc Number of arguments passed to the server executable (see main()). + * @param argv Array of arguments passed to the server executable (see main()). + * @param cfg Root libconfig object of global configuration file. + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ + int (*init)(int argc, char * argv[], config_setting_t *cfg); + + /** Global de-initialization per node type. + * + * This callback is invoked once per node-type. + * + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ + int (*deinit)(); + + /** Allocate memory for an instance of this type. + * + * @return A pointer to the node-type specific private data. + */ + void * (*create)(); + + /** Free memory of an instance of this type. + * + * @param n A pointer to the node object. + */ + int (*destroy)(struct node *n); + + /** Parse node connection details.‚ + * + * @param n A pointer to the node object. + * @param cfg A libconfig object pointing to the node. + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ + int (*parse)(struct node *n, config_setting_t *cfg); + + /** Returns a string with a textual represenation of this node. + * + * @param n A pointer to the node object. + * @return A pointer to a dynamically allocated string. Must be freed(). + */ + char * (*print)(struct node *n); + + /** Opens the connection to this node. + * + * @param n A pointer to the node object. + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ + int (*open) (struct node *n); + + /** Close the connection to this node. + * + * @param n A pointer to the node object. + * @retval 0 Success. Everything went well. + * @retval <0 Error. Something went wrong. + */ + int (*close)(struct node *n); + + /** Receive multiple messages at once. + * + * Messages are received with a single recvmsg() syscall by + * using gathering techniques (struct iovec). + * The messages will be stored in a circular buffer / array @p m. + * Indexes used to address @p m will wrap around after len messages. + * Some node types might only support to receive one message at a time. + * + * @param n A pointer to the node object. + * @param smps An array of pointers to memory blocks where the function should store received samples. + * @param cnt The number of messages which should be received. + * @return The number of messages actually received. + */ + int (*read) (struct node *n, struct sample *smps[], unsigned cnt); + + /** Send multiple messages in a single datagram / packet. + * + * Messages are sent with a single sendmsg() syscall by + * using gathering techniques (struct iovec). + * The messages have to be stored in a circular buffer / array m. + * So the indexes will wrap around after len. + * + * @param n A pointer to the node object. + * @param smps An array of pointers to memory blocks where samples read from. + * @param cnt The number of messages which should be sent. + * @return The number of messages actually sent. + */ + int (*write)(struct node *n, struct sample *smps[], unsigned cnt); + + /** Reverse source and destination of a node. + * + * This is not supported by all node types! + * + * @param n A pointer to the node object. + */ + int (*reverse)(struct node *n); +}; + +/** Initialize all registered node type subsystems. + * + * @see node_type::init + */ +int node_type_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg); + +/** De-initialize node type subsystems. + * + * @see node_type::deinit + */ +int node_type_deinit(struct node_type *vt); + +/** @} */ \ No newline at end of file diff --git a/lib/Makefile.inc b/lib/Makefile.inc index a11c5485e..60c598c9a 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -6,7 +6,8 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \ $(addprefix lib/kernel/, kernel.c rt.c) \ $(addprefix lib/, sample.c path.c node.c hook.c \ log.c utils.c cfg.c hist.c timing.c pool.c list.c \ - queue.c memory.c advio.c web.c api.c plugin.c stats.c \ + queue.c memory.c advio.c web.c api.c plugin.c \ + node_type.c stats.c \ ) LIB_CFLAGS = $(CFLAGS) -fPIC diff --git a/lib/node.c b/lib/node.c index f4fd8f9fd..19ce08920 100644 --- a/lib/node.c +++ b/lib/node.c @@ -57,42 +57,6 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt) return nsent; } -int node_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg) -{ - int ret; - - if (vt->state != NODE_TYPE_UNINITIALIZED) - return -1; - - info("Initializing " YEL("%s") " node type", vt->name); - { INDENT - ret = vt->init ? vt->init(argc, argv, cfg) : -1; - } - - if (ret == 0) - vt->state = NODE_TYPE_INITIALIZED; - - return ret; -} - -int node_deinit(struct node_type *vt) -{ - int ret; - - if (vt->state != NODE_TYPE_INITIALIZED) - return -1; - - info("De-initializing " YEL("%s") " node type", vt->name); - { INDENT - ret = vt->deinit ? vt->deinit() : -1; - } - - if (ret == 0) - vt->state = NODE_TYPE_UNINITIALIZED; - - return ret; -} - int node_start(struct node *n) { int ret; @@ -163,11 +127,6 @@ const char * node_name_short(struct node *n) return n->name; } -const char * node_name_type(struct node *n) -{ - return n->_vt->name; -} - int node_reverse(struct node *n) { return n->_vt->reverse ? n->_vt->reverse(n) : -1; diff --git a/lib/node_type.c b/lib/node_type.c new file mode 100644 index 000000000..75b5baa3f --- /dev/null +++ b/lib/node_type.c @@ -0,0 +1,51 @@ +/** Nodes. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + *********************************************************************************/ + +#include +#include + +#include "sample.h" +#include "node.h" +#include "cfg.h" +#include "utils.h" +#include "config.h" +#include "plugin.h" + +int node_type_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg) +{ + int ret; + + if (vt->state != NODE_TYPE_UNINITIALIZED) + return -1; + + info("Initializing " YEL("%s") " node type", vt->name); + { INDENT + ret = vt->init ? vt->init(argc, argv, cfg) : -1; + } + + if (ret == 0) + vt->state = NODE_TYPE_INITIALIZED; + + return ret; +} + +int node_type_deinit(struct node_type *vt) +{ + int ret; + + if (vt->state != NODE_TYPE_INITIALIZED) + return -1; + + info("De-initializing " YEL("%s") " node type", vt->name); + { INDENT + ret = vt->deinit ? vt->deinit() : -1; + } + + if (ret == 0) + vt->state = NODE_TYPE_UNINITIALIZED; + + return ret; +} diff --git a/src/node.c b/src/node.c index c73069b7e..795470306 100644 --- a/src/node.c +++ b/src/node.c @@ -104,8 +104,6 @@ int main(int argc, char *argv[]) } else if (argc > 2) usage(); - - char *uri = (argc == 2) ? argv[1] : NULL; #endif log_init(&cfg.log, V, LOG_ALL); @@ -123,7 +121,7 @@ int main(int argc, char *argv[]) info("Parsing configuration"); cfg_init_pre(&cfg); - cfg_parse(&cfg, uri); + cfg_parse_cli(&cfg, argc, argv); cfg_init_post(&cfg); diff --git a/src/pipe.c b/src/pipe.c index a92005c77..4f3e77762 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -54,7 +54,7 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) } node_stop(node); - node_deinit(node->_vt); + node_type_deinit(node->_vt); cfg_destroy(&cfg); @@ -229,7 +229,7 @@ int main(int argc, char *argv[]) if (reverse) node_reverse(node); - ret = node_init(node->_vt, argc-optind, argv+optind, config_root_setting(&cfg.cfg)); + ret = node_type_init(node->_vt, argc-optind, argv+optind, config_root_setting(&cfg.cfg)); if (ret) error("Failed to intialize node: %s", node_name(node)); diff --git a/src/test.c b/src/test.c index 2b55bac5b..37d48cea7 100644 --- a/src/test.c +++ b/src/test.c @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) if (!node) error("There's no node with the name '%s'", argv[3]); - node_init(node->_vt, argc-3, argv+3, config_root_setting(&cfg.cfg)); + node_type_init(node->_vt, argc-3, argv+3, config_root_setting(&cfg.cfg)); node_start(node); /* Parse Arguments */ @@ -132,7 +132,7 @@ check: if (optarg == endptr) error("Unknown test: '%s'", argv[2]); node_stop(node); - node_deinit(node->_vt); + node_type_deinit(node->_vt); cfg_destroy(&cfg); From 4ceb3b573db1eb59aef6d5189c839fdb0ea8ed17 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 6 Mar 2017 08:59:28 -0400 Subject: [PATCH 099/211] add new cfg_parse_cli function --- include/villas/cfg.h | 7 +++++++ lib/cfg.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/villas/cfg.h b/include/villas/cfg.h index 9c8581ee2..d8b940ad4 100644 --- a/include/villas/cfg.h +++ b/include/villas/cfg.h @@ -31,6 +31,11 @@ struct cfg { struct log log; struct api api; struct web web; + + struct { + int argc; + char **argv; + } cli; config_t cfg; /**< Pointer to configuration file */ json_t *json; /**< JSON representation of the same config. */ @@ -60,3 +65,5 @@ int cfg_destroy(struct cfg *cfg); * @retval <0 Error. Something went wrong. */ int cfg_parse(struct cfg *cfg, const char *uri); + +int cfg_parse_cli(struct cfg *cfg, int argc, char *argv[]); \ No newline at end of file diff --git a/lib/cfg.c b/lib/cfg.c index 6d4eafae5..e55f2bc1c 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -97,6 +97,16 @@ int cfg_destroy(struct cfg *cfg) return 0; } +int cfg_parse_cli(struct cfg *cfg, int argc, char *argv[]) +{ + cfg->cli.argc = argc; + cfg->cli.argv = argv; + + char *uri = (argc == 2) ? argv[1] : NULL; + + return cfg_parse(cfg, uri); +} + int cfg_parse(struct cfg *cfg, const char *uri) { config_setting_t *cfg_root, *cfg_nodes, *cfg_paths, *cfg_plugins, *cfg_logging, *cfg_web; From 7d4afa6bf72347c04ea72a26ae6a97e969958878 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 6 Mar 2017 08:59:58 -0400 Subject: [PATCH 100/211] move checks for node from node_parse to node_check --- lib/node.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/node.c b/lib/node.c index 19ce08920..fb600fa78 100644 --- a/lib/node.c +++ b/lib/node.c @@ -7,7 +7,6 @@ #include #include - #include "sample.h" #include "node.h" #include "cfg.h" @@ -163,16 +162,6 @@ int node_destroy(struct node *n) return 0; } -/** Parse an array or single node and checks if they exist in the "nodes" section. - * - * Examples: - * out = [ "sintef", "scedu" ] - * out = "acs" - * - * @param cfg The libconfig object handle for "out". - * @param nodes The nodes will be added to this list. - * @param all This list contains all valid nodes. - */ int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all) { const char *str; struct node *node; @@ -241,18 +230,17 @@ int node_parse(struct node *n, config_setting_t *cfg) if (ret) cerror(cfg, "Failed to parse node '%s'", node_name(n)); - if (config_setting_lookup_int(cfg, "vectorize", &n->vectorize)) { - config_setting_t *cfg_vectorize = config_setting_lookup(cfg, "vectorize"); - - if (n->vectorize <= 0) - cerror(cfg_vectorize, "Invalid value for `vectorize` %d. Must be natural number!", n->vectorize); - if (vt->vectorize && vt->vectorize < n->vectorize) - cerror(cfg_vectorize, "Invalid value for `vectorize`. Node type %s requires a number smaller than %d!", - node_name_type(n), vt->vectorize); - } - else - n->vectorize = 1; - return ret; } +int node_check(struct node *n) +{ + if (n->vectorize <= 0) + error("Invalid `vectorize` value %d for node %s. Must be natural number!", n->vectorize, node_name(n)); + + if (n->_vt->vectorize && n->_vt->vectorize < n->vectorize) + error("Invalid value for `vectorize`. Node type requires a number smaller than %d!", + n->_vt->vectorize); + + return 0; +} From 31ad580938f71e921d1dfe3fb077ed18a8986d23 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 6 Mar 2017 10:06:33 -0400 Subject: [PATCH 101/211] removed libxil which is going to be maintained in a submodule --- .gitmodules | 3 + thirdparty/libxil | 1 + thirdparty/libxil/.gitignore | 1 - thirdparty/libxil/CMakeLists.txt | 36 - thirdparty/libxil/README.md | 1 - thirdparty/libxil/include/xilinx/xaxidma.h | 741 --- thirdparty/libxil/include/xilinx/xaxidma_bd.h | 679 --- .../libxil/include/xilinx/xaxidma_bdring.h | 526 -- thirdparty/libxil/include/xilinx/xaxidma_hw.h | 344 -- .../include/xilinx/xaxidma_porting_guide.h | 254 - .../libxil/include/xilinx/xaxis_switch.h | 208 - .../libxil/include/xilinx/xaxis_switch_hw.h | 167 - .../libxil/include/xilinx/xbasic_types.h | 315 - thirdparty/libxil/include/xilinx/xdebug.h | 93 - thirdparty/libxil/include/xilinx/xenv.h | 191 - thirdparty/libxil/include/xilinx/xenv_linux.h | 255 - thirdparty/libxil/include/xilinx/xenv_none.h | 55 - .../libxil/include/xilinx/xenv_standalone.h | 370 -- .../libxil/include/xilinx/xenv_vxworks.h | 272 - thirdparty/libxil/include/xilinx/xhls_dft.h | 77 - .../libxil/include/xilinx/xhls_dft_hw.h | 52 - thirdparty/libxil/include/xilinx/xil_assert.h | 85 - thirdparty/libxil/include/xilinx/xil_cache.h | 71 - thirdparty/libxil/include/xilinx/xil_io.h | 246 - thirdparty/libxil/include/xilinx/xil_printf.h | 43 - thirdparty/libxil/include/xilinx/xil_types.h | 200 - thirdparty/libxil/include/xilinx/xintc.h | 370 -- thirdparty/libxil/include/xilinx/xintc_l.h | 330 - thirdparty/libxil/include/xilinx/xllfifo.h | 715 --- thirdparty/libxil/include/xilinx/xllfifo_hw.h | 242 - .../libxil/include/xilinx/xparameters.h | 16 - thirdparty/libxil/include/xilinx/xstatus.h | 432 -- thirdparty/libxil/include/xilinx/xstreamer.h | 333 - thirdparty/libxil/include/xilinx/xtmrctr.h | 303 - thirdparty/libxil/include/xilinx/xtmrctr_i.h | 80 - thirdparty/libxil/include/xilinx/xtmrctr_l.h | 429 -- thirdparty/libxil/include/xilinx/xutil.h | 167 - thirdparty/libxil/include/xilinx/xversion.h | 111 - thirdparty/libxil/libxil.pc.in | 10 - thirdparty/libxil/orig/README.md | 1 - .../libxil/orig/axidma_v9_0/data/axidma.mdd | 43 - .../libxil/orig/axidma_v9_0/data/axidma.tcl | 208 - .../orig/axidma_v9_0/data/axidma_header.h | 41 - .../orig/axidma_v9_0/data/axidma_tapp.tcl | 121 - .../axidma_v9_0/doc/html/api/HTML_custom.css | 1430 ----- .../axidma_v9_0/doc/html/api/annotated.html | 66 - .../axidma_v9_0/doc/html/api/classes.html | 68 - .../orig/axidma_v9_0/doc/html/api/doc.png | Bin 746 -> 0 bytes .../axidma_v9_0/doc/html/api/dynsections.js | 97 - .../orig/axidma_v9_0/doc/html/api/files.html | 68 - .../axidma_v9_0/doc/html/api/functions.html | 130 - .../doc/html/api/functions_vars.html | 130 - .../axidma_v9_0/doc/html/api/globals.html | 558 -- .../doc/html/api/globals_defs.html | 456 -- .../doc/html/api/globals_func.html | 162 - .../doc/html/api/globals_type.html | 65 - .../doc/html/api/group__axidma__v9__0.html | 5350 ----------------- .../orig/axidma_v9_0/doc/html/api/index.html | 261 - .../orig/axidma_v9_0/doc/html/api/jquery.js | 68 - .../axidma_v9_0/doc/html/api/modules.html | 58 - .../doc/html/api/struct_x_axi_dma.html | 78 - .../html/api/struct_x_axi_dma___bd_ring.html | 398 -- .../html/api/struct_x_axi_dma___config.html | 78 - .../orig/axidma_v9_0/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../orig/axidma_v9_0/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../orig/axidma_v9_0/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../orig/axidma_v9_0/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../orig/axidma_v9_0/doc/html/api/tabs.css | 60 - .../axidma_v9_0/doc/html/api/xaxidma_8c.html | 81 - .../axidma_v9_0/doc/html/api/xaxidma_8h.html | 121 - .../doc/html/api/xaxidma__bd_8c.html | 77 - .../doc/html/api/xaxidma__bd_8h.html | 131 - .../doc/html/api/xaxidma__bdring_8c.html | 91 - .../doc/html/api/xaxidma__bdring_8h.html | 135 - .../doc/html/api/xaxidma__g_8c.html | 57 - .../doc/html/api/xaxidma__hw_8h.html | 95 - .../html/api/xaxidma__porting__guide_8h.html | 57 - .../doc/html/api/xaxidma__selftest_8c.html | 65 - .../doc/html/api/xaxidma__sinit_8c.html | 65 - .../axidma_v9_0/doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../orig/axidma_v9_0/examples/index.html | 22 - .../examples/xaxidma_example_selftest.c | 147 - .../examples/xaxidma_example_sg_intr.c | 1214 ---- .../examples/xaxidma_example_sg_poll.c | 701 --- .../examples/xaxidma_example_simple_intr.c | 753 --- .../examples/xaxidma_example_simple_poll.c | 362 -- .../examples/xaxidma_multichan_sg_intr.c | 1317 ---- .../examples/xaxidma_poll_multi_pkts.c | 696 --- .../libxil/orig/axidma_v9_0/src/Makefile | 27 - .../libxil/orig/axidma_v9_0/src/xaxidma.c | 974 --- .../libxil/orig/axidma_v9_0/src/xaxidma.h | 741 --- .../libxil/orig/axidma_v9_0/src/xaxidma_bd.c | 354 -- .../libxil/orig/axidma_v9_0/src/xaxidma_bd.h | 679 --- .../orig/axidma_v9_0/src/xaxidma_bdring.c | 1587 ----- .../orig/axidma_v9_0/src/xaxidma_bdring.h | 526 -- .../libxil/orig/axidma_v9_0/src/xaxidma_g.c | 88 - .../libxil/orig/axidma_v9_0/src/xaxidma_hw.h | 344 -- .../axidma_v9_0/src/xaxidma_porting_guide.h | 254 - .../orig/axidma_v9_0/src/xaxidma_selftest.c | 115 - .../orig/axidma_v9_0/src/xaxidma_sinit.c | 95 - .../axis_switch_v1_0/data/axis_switch.mdd | 40 - .../axis_switch_v1_0/data/axis_switch.tcl | 36 - .../doc/html/api/HTML_custom.css | 1430 ----- .../doc/html/api/annotated.html | 65 - .../doc/html/api/classes.html | 68 - .../axis_switch_v1_0/doc/html/api/doc.png | Bin 746 -> 0 bytes .../doc/html/api/dynsections.js | 97 - .../axis_switch_v1_0/doc/html/api/files.html | 63 - .../doc/html/api/functions.html | 81 - .../doc/html/api/functions_vars.html | 81 - .../doc/html/api/globals.html | 127 - .../doc/html/api/globals_defs.html | 103 - .../doc/html/api/globals_func.html | 82 - .../html/api/group__axis__switch__v1__0.html | 786 --- .../axis_switch_v1_0/doc/html/api/index.html | 76 - .../axis_switch_v1_0/doc/html/api/jquery.js | 68 - .../doc/html/api/modules.html | 58 - .../doc/html/api/struct_x_axis___switch.html | 94 - .../api/struct_x_axis___switch___config.html | 122 - .../axis_switch_v1_0/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../axis_switch_v1_0/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../axis_switch_v1_0/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../axis_switch_v1_0/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../axis_switch_v1_0/doc/html/api/tabs.css | 60 - .../doc/html/api/xaxis__switch_8c.html | 75 - .../doc/html/api/xaxis__switch_8h.html | 95 - .../doc/html/api/xaxis__switch__g_8c.html | 57 - .../doc/html/api/xaxis__switch__hw_8h.html | 71 - .../html/api/xaxis__switch__selftest_8c.html | 65 - .../doc/html/api/xaxis__switch__sinit_8c.html | 65 - .../doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../orig/axis_switch_v1_0/examples/index.html | 17 - .../examples/xaxis_switch_example.c | 179 - .../libxil/orig/axis_switch_v1_0/src/Makefile | 40 - .../orig/axis_switch_v1_0/src/xaxis_switch.c | 313 - .../orig/axis_switch_v1_0/src/xaxis_switch.h | 208 - .../axis_switch_v1_0/src/xaxis_switch_g.c | 75 - .../axis_switch_v1_0/src/xaxis_switch_hw.h | 167 - .../src/xaxis_switch_selftest.c | 113 - .../axis_switch_v1_0/src/xaxis_switch_sinit.c | 118 - .../vxworks5_4/xtag_csp_common_v1_00_a.c | 53 - .../orig/common_v1_00_a/data/common.mdd | 41 - .../doc/html/api/HTML_custom.css | 1430 ----- .../doc/html/api/annotated.html | 63 - .../common_v1_00_a/doc/html/api/classes.html | 67 - .../orig/common_v1_00_a/doc/html/api/doc.png | Bin 746 -> 0 bytes .../doc/html/api/dynsections.js | 97 - .../common_v1_00_a/doc/html/api/files.html | 70 - .../common_v1_00_a/doc/html/api/globals.html | 210 - .../doc/html/api/globals_defs.html | 120 - .../doc/html/api/globals_func.html | 96 - .../doc/html/api/globals_type.html | 100 - .../doc/html/api/globals_vars.html | 67 - .../html/api/group__common__v1__00__a.html | 1948 ------ .../common_v1_00_a/doc/html/api/index.html | 53 - .../common_v1_00_a/doc/html/api/jquery.js | 68 - .../common_v1_00_a/doc/html/api/modules.html | 58 - .../struct_x_e_n_v___t_i_m_e___s_t_a_m_p.html | 60 - .../common_v1_00_a/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../common_v1_00_a/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../common_v1_00_a/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../common_v1_00_a/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../orig/common_v1_00_a/doc/html/api/tabs.css | 60 - .../doc/html/api/xbasic__types_8c.html | 77 - .../doc/html/api/xbasic__types_8h.html | 109 - .../common_v1_00_a/doc/html/api/xenv_8h.html | 57 - .../doc/html/api/xenv__linux_8h.html | 81 - .../doc/html/api/xenv__none_8h.html | 57 - .../doc/html/api/xenv__standalone_8h.html | 81 - .../doc/html/api/xenv__vxworks_8h.html | 81 - .../common_v1_00_a/doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../doc/html/api/xparameters_8h.html | 57 - .../doc/html/api/xstatus_8h.html | 57 - .../common_v1_00_a/doc/html/api/xutil_8h.html | 69 - .../doc/html/api/xutil__memtest_8c.html | 69 - .../doc/html/api/xversion_8c.html | 75 - .../doc/html/api/xversion_8h.html | 75 - .../libxil/orig/common_v1_00_a/src/Makefile | 28 - .../orig/common_v1_00_a/src/xbasic_types.c | 150 - .../orig/common_v1_00_a/src/xbasic_types.h | 315 - .../libxil/orig/common_v1_00_a/src/xenv.h | 191 - .../orig/common_v1_00_a/src/xenv_linux.h | 255 - .../orig/common_v1_00_a/src/xenv_none.h | 55 - .../orig/common_v1_00_a/src/xenv_standalone.h | 370 -- .../orig/common_v1_00_a/src/xenv_vxworks.h | 272 - .../orig/common_v1_00_a/src/xparameters.h | 731 --- .../libxil/orig/common_v1_00_a/src/xstatus.h | 432 -- .../libxil/orig/common_v1_00_a/src/xutil.h | 167 - .../orig/common_v1_00_a/src/xutil_memtest.c | 1186 ---- .../libxil/orig/common_v1_00_a/src/xversion.c | 357 -- .../libxil/orig/common_v1_00_a/src/xversion.h | 111 - .../libxil/orig/hls_dft_v1_0/data/hls_dft.mdd | 19 - .../libxil/orig/hls_dft_v1_0/data/hls_dft.tcl | 24 - .../libxil/orig/hls_dft_v1_0/src/Makefile | 35 - .../libxil/orig/hls_dft_v1_0/src/xhls_dft.c | 260 - .../libxil/orig/hls_dft_v1_0/src/xhls_dft.h | 77 - .../orig/hls_dft_v1_0/src/xhls_dft_hw.h | 52 - .../orig/hls_dft_v1_0/src/xhls_dft_sinit.c | 46 - .../libxil/orig/intc_v3_4/data/intc.mdd | 73 - .../libxil/orig/intc_v3_4/data/intc.tcl | 692 --- .../libxil/orig/intc_v3_4/data/intc_header.h | 42 - .../libxil/orig/intc_v3_4/data/intc_tapp.tcl | 206 - .../intc_v3_4/doc/html/api/HTML_custom.css | 1430 ----- .../intc_v3_4/doc/html/api/annotated.html | 65 - .../orig/intc_v3_4/doc/html/api/classes.html | 68 - .../orig/intc_v3_4/doc/html/api/doc.png | Bin 746 -> 0 bytes .../intc_v3_4/doc/html/api/dynsections.js | 97 - .../orig/intc_v3_4/doc/html/api/files.html | 66 - .../intc_v3_4/doc/html/api/functions.html | 103 - .../doc/html/api/functions_vars.html | 103 - .../orig/intc_v3_4/doc/html/api/globals.html | 157 - .../intc_v3_4/doc/html/api/globals_defs.html | 86 - .../intc_v3_4/doc/html/api/globals_func.html | 119 - .../intc_v3_4/doc/html/api/globals_vars.html | 63 - .../doc/html/api/group__intc__v3__4.html | 1343 ----- .../orig/intc_v3_4/doc/html/api/index.html | 171 - .../orig/intc_v3_4/doc/html/api/jquery.js | 68 - .../orig/intc_v3_4/doc/html/api/modules.html | 58 - .../intc_v3_4/doc/html/api/struct_x_intc.html | 140 - .../doc/html/api/struct_x_intc___config.html | 202 - .../orig/intc_v3_4/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../orig/intc_v3_4/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../orig/intc_v3_4/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../orig/intc_v3_4/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../orig/intc_v3_4/doc/html/api/tabs.css | 60 - .../orig/intc_v3_4/doc/html/api/xintc_8c.html | 85 - .../orig/intc_v3_4/doc/html/api/xintc_8h.html | 116 - .../intc_v3_4/doc/html/api/xintc__g_8c.html | 65 - .../intc_v3_4/doc/html/api/xintc__i_8h.html | 65 - .../doc/html/api/xintc__intr_8c.html | 65 - .../intc_v3_4/doc/html/api/xintc__l_8c.html | 71 - .../intc_v3_4/doc/html/api/xintc__l_8h.html | 87 - .../doc/html/api/xintc__options_8c.html | 67 - .../doc/html/api/xintc__selftest_8c.html | 67 - .../orig/intc_v3_4/doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../libxil/orig/intc_v3_4/examples/index.html | 19 - .../orig/intc_v3_4/examples/xintc_example.c | 348 -- .../examples/xintc_low_level_example.c | 302 - .../intc_v3_4/examples/xintc_tapp_example.c | 250 - thirdparty/libxil/orig/intc_v3_4/src/Makefile | 28 - thirdparty/libxil/orig/intc_v3_4/src/xintc.c | 1081 ---- thirdparty/libxil/orig/intc_v3_4/src/xintc.h | 370 -- .../libxil/orig/intc_v3_4/src/xintc_g.c | 110 - .../libxil/orig/intc_v3_4/src/xintc_i.h | 93 - .../libxil/orig/intc_v3_4/src/xintc_intr.c | 176 - .../libxil/orig/intc_v3_4/src/xintc_l.c | 665 -- .../libxil/orig/intc_v3_4/src/xintc_l.h | 330 - .../libxil/orig/intc_v3_4/src/xintc_options.c | 149 - .../orig/intc_v3_4/src/xintc_selftest.c | 255 - .../libxil/orig/llfifo_v5_0/data/llfifo.mdd | 47 - .../libxil/orig/llfifo_v5_0/data/llfifo.tcl | 53 - .../llfifo_v5_0/doc/html/api/HTML_custom.css | 1430 ----- .../llfifo_v5_0/doc/html/api/annotated.html | 66 - .../llfifo_v5_0/doc/html/api/classes.html | 68 - .../orig/llfifo_v5_0/doc/html/api/doc.png | Bin 746 -> 0 bytes .../llfifo_v5_0/doc/html/api/dynsections.js | 97 - .../orig/llfifo_v5_0/doc/html/api/files.html | 60 - .../llfifo_v5_0/doc/html/api/functions.html | 116 - .../doc/html/api/functions_vars.html | 116 - .../llfifo_v5_0/doc/html/api/globals.html | 246 - .../doc/html/api/globals_defs.html | 234 - .../doc/html/api/globals_func.html | 68 - .../doc/html/api/globals_type.html | 62 - .../doc/html/api/group__llfifo__v5__0.html | 1623 ----- .../orig/llfifo_v5_0/doc/html/api/index.html | 141 - .../orig/llfifo_v5_0/doc/html/api/jquery.js | 68 - .../llfifo_v5_0/doc/html/api/modules.html | 58 - .../doc/html/api/struct_x_ll_fifo.html | 165 - .../api/struct_x_strm___rx_fifo_streamer.html | 158 - .../api/struct_x_strm___tx_fifo_streamer.html | 144 - .../orig/llfifo_v5_0/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../orig/llfifo_v5_0/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../orig/llfifo_v5_0/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../orig/llfifo_v5_0/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../orig/llfifo_v5_0/doc/html/api/tabs.css | 60 - .../llfifo_v5_0/doc/html/api/xllfifo_8c.html | 67 - .../llfifo_v5_0/doc/html/api/xllfifo_8h.html | 117 - .../doc/html/api/xllfifo__hw_8h.html | 74 - .../llfifo_v5_0/doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../orig/llfifo_v5_0/examples/index.html | 18 - .../examples/xllfifo_interrupt_example.c | 619 -- .../examples/xllfifo_polling_example.c | 361 -- .../libxil/orig/llfifo_v5_0/src/Makefile | 27 - .../libxil/orig/llfifo_v5_0/src/xllfifo.c | 498 -- .../libxil/orig/llfifo_v5_0/src/xllfifo.h | 715 --- .../libxil/orig/llfifo_v5_0/src/xllfifo_g.c | 71 - .../libxil/orig/llfifo_v5_0/src/xllfifo_hw.h | 242 - .../orig/llfifo_v5_0/src/xllfifo_sinit.c | 88 - .../libxil/orig/llfifo_v5_0/src/xstreamer.c | 516 -- .../libxil/orig/llfifo_v5_0/src/xstreamer.h | 333 - .../libxil/orig/tmrctr_v4_0/data/tmrctr.mdd | 61 - .../libxil/orig/tmrctr_v4_0/data/tmrctr.tcl | 173 - .../orig/tmrctr_v4_0/data/tmrctr_header.h | 42 - .../tmrctr_v4_0/data/tmrctr_intr_header.h | 53 - .../orig/tmrctr_v4_0/data/tmrctr_tapp.tcl | 236 - .../tmrctr_v4_0/doc/html/api/HTML_custom.css | 1430 ----- .../tmrctr_v4_0/doc/html/api/annotated.html | 66 - .../tmrctr_v4_0/doc/html/api/classes.html | 68 - .../orig/tmrctr_v4_0/doc/html/api/doc.png | Bin 746 -> 0 bytes .../tmrctr_v4_0/doc/html/api/dynsections.js | 97 - .../orig/tmrctr_v4_0/doc/html/api/files.html | 68 - .../tmrctr_v4_0/doc/html/api/functions.html | 97 - .../doc/html/api/functions_vars.html | 97 - .../tmrctr_v4_0/doc/html/api/globals.html | 218 - .../doc/html/api/globals_defs.html | 150 - .../doc/html/api/globals_func.html | 114 - .../doc/html/api/globals_type.html | 63 - .../doc/html/api/globals_vars.html | 64 - .../doc/html/api/group__tmrctr__v3__0.html | 53 - .../doc/html/api/group__tmrctr__v4__0.html | 1909 ------ .../orig/tmrctr_v4_0/doc/html/api/index.html | 119 - .../orig/tmrctr_v4_0/doc/html/api/jquery.js | 68 - .../tmrctr_v4_0/doc/html/api/modules.html | 59 - .../doc/html/api/struct_x_tmr_ctr.html | 198 - .../html/api/struct_x_tmr_ctr___config.html | 104 - .../doc/html/api/struct_x_tmr_ctr_stats.html | 76 - .../orig/tmrctr_v4_0/doc/html/api/tab_a.png | Bin 142 -> 0 bytes .../orig/tmrctr_v4_0/doc/html/api/tab_b.png | Bin 169 -> 0 bytes .../orig/tmrctr_v4_0/doc/html/api/tab_h.png | Bin 177 -> 0 bytes .../orig/tmrctr_v4_0/doc/html/api/tab_s.png | Bin 184 -> 0 bytes .../orig/tmrctr_v4_0/doc/html/api/tabs.css | 60 - .../tmrctr_v4_0/doc/html/api/xlogo_bg.gif | Bin 3154 -> 0 bytes .../tmrctr_v4_0/doc/html/api/xtmrctr_8c.html | 83 - .../tmrctr_v4_0/doc/html/api/xtmrctr_8h.html | 123 - .../doc/html/api/xtmrctr__g_8c.html | 57 - .../doc/html/api/xtmrctr__i_8h.html | 57 - .../doc/html/api/xtmrctr__intr_8c.html | 67 - .../doc/html/api/xtmrctr__l_8c.html | 57 - .../doc/html/api/xtmrctr__l_8h.html | 113 - .../doc/html/api/xtmrctr__options_8c.html | 67 - .../doc/html/api/xtmrctr__selftest_8c.html | 65 - .../doc/html/api/xtmrctr__sinit_8c.html | 65 - .../doc/html/api/xtmrctr__stats_8c.html | 67 - .../orig/tmrctr_v4_0/examples/index.html | 22 - .../examples/xtmrctr_fast_intr_example.c | 451 -- .../examples/xtmrctr_intr_64bit_example.c | 464 -- .../examples/xtmrctr_intr_example.c | 519 -- .../examples/xtmrctr_low_level_example.c | 200 - .../examples/xtmrctr_polled_example.c | 209 - .../examples/xtmrctr_selftest_example.c | 161 - .../libxil/orig/tmrctr_v4_0/src/Makefile | 28 - .../libxil/orig/tmrctr_v4_0/src/xtmrctr.c | 536 -- .../libxil/orig/tmrctr_v4_0/src/xtmrctr.h | 303 - .../libxil/orig/tmrctr_v4_0/src/xtmrctr_g.c | 87 - .../libxil/orig/tmrctr_v4_0/src/xtmrctr_i.h | 80 - .../orig/tmrctr_v4_0/src/xtmrctr_intr.c | 233 - .../libxil/orig/tmrctr_v4_0/src/xtmrctr_l.c | 79 - .../libxil/orig/tmrctr_v4_0/src/xtmrctr_l.h | 429 -- .../orig/tmrctr_v4_0/src/xtmrctr_options.c | 217 - .../orig/tmrctr_v4_0/src/xtmrctr_selftest.c | 166 - .../orig/tmrctr_v4_0/src/xtmrctr_sinit.c | 102 - .../orig/tmrctr_v4_0/src/xtmrctr_stats.c | 115 - thirdparty/libxil/src/xil_io.c | 342 -- 353 files changed, 4 insertions(+), 77129 deletions(-) create mode 160000 thirdparty/libxil delete mode 100644 thirdparty/libxil/.gitignore delete mode 100644 thirdparty/libxil/CMakeLists.txt delete mode 100644 thirdparty/libxil/README.md delete mode 100644 thirdparty/libxil/include/xilinx/xaxidma.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxidma_bd.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxidma_bdring.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxidma_hw.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxidma_porting_guide.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxis_switch.h delete mode 100644 thirdparty/libxil/include/xilinx/xaxis_switch_hw.h delete mode 100644 thirdparty/libxil/include/xilinx/xbasic_types.h delete mode 100644 thirdparty/libxil/include/xilinx/xdebug.h delete mode 100644 thirdparty/libxil/include/xilinx/xenv.h delete mode 100644 thirdparty/libxil/include/xilinx/xenv_linux.h delete mode 100644 thirdparty/libxil/include/xilinx/xenv_none.h delete mode 100644 thirdparty/libxil/include/xilinx/xenv_standalone.h delete mode 100644 thirdparty/libxil/include/xilinx/xenv_vxworks.h delete mode 100644 thirdparty/libxil/include/xilinx/xhls_dft.h delete mode 100644 thirdparty/libxil/include/xilinx/xhls_dft_hw.h delete mode 100644 thirdparty/libxil/include/xilinx/xil_assert.h delete mode 100644 thirdparty/libxil/include/xilinx/xil_cache.h delete mode 100644 thirdparty/libxil/include/xilinx/xil_io.h delete mode 100644 thirdparty/libxil/include/xilinx/xil_printf.h delete mode 100644 thirdparty/libxil/include/xilinx/xil_types.h delete mode 100644 thirdparty/libxil/include/xilinx/xintc.h delete mode 100644 thirdparty/libxil/include/xilinx/xintc_l.h delete mode 100644 thirdparty/libxil/include/xilinx/xllfifo.h delete mode 100644 thirdparty/libxil/include/xilinx/xllfifo_hw.h delete mode 100644 thirdparty/libxil/include/xilinx/xparameters.h delete mode 100644 thirdparty/libxil/include/xilinx/xstatus.h delete mode 100644 thirdparty/libxil/include/xilinx/xstreamer.h delete mode 100644 thirdparty/libxil/include/xilinx/xtmrctr.h delete mode 100644 thirdparty/libxil/include/xilinx/xtmrctr_i.h delete mode 100644 thirdparty/libxil/include/xilinx/xtmrctr_l.h delete mode 100644 thirdparty/libxil/include/xilinx/xutil.h delete mode 100644 thirdparty/libxil/include/xilinx/xversion.h delete mode 100644 thirdparty/libxil/libxil.pc.in delete mode 100644 thirdparty/libxil/orig/README.md delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/data/axidma.mdd delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/data/axidma.tcl delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/data/axidma_header.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/data/axidma_tapp.tcl delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions_vars.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_type.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/group__axidma__v9__0.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/struct_x_axi_dma.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/struct_x_axi_dma___bd_ring.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/struct_x_axi_dma___config.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma_8h.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__bd_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__bd_8h.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__bdring_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__bdring_8h.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__g_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__hw_8h.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__porting__guide_8h.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__selftest_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xaxidma__sinit_8c.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/index.html delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_example_selftest.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_example_sg_intr.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_example_sg_poll.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_example_simple_intr.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_example_simple_poll.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_multichan_sg_intr.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/examples/xaxidma_poll_multi_pkts.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/Makefile delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_bd.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_bd.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_bdring.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_bdring.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_g.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_hw.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_porting_guide.h delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_selftest.c delete mode 100644 thirdparty/libxil/orig/axidma_v9_0/src/xaxidma_sinit.c delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/data/axis_switch.mdd delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/data/axis_switch.tcl delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/functions.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/functions_vars.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/group__axis__switch__v1__0.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/struct_x_axis___switch.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/struct_x_axis___switch___config.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch_8c.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch_8h.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch__g_8c.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch__hw_8h.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch__selftest_8c.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xaxis__switch__sinit_8c.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/examples/index.html delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/examples/xaxis_switch_example.c delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/Makefile delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch.c delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch.h delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch_g.c delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch_hw.h delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch_selftest.c delete mode 100644 thirdparty/libxil/orig/axis_switch_v1_0/src/xaxis_switch_sinit.c delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/build/vxworks5_4/xtag_csp_common_v1_00_a.c delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/data/common.mdd delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/globals_type.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/globals_vars.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/group__common__v1__00__a.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/struct_x_e_n_v___t_i_m_e___s_t_a_m_p.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xbasic__types_8c.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xbasic__types_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xenv_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xenv__linux_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xenv__none_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xenv__standalone_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xenv__vxworks_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xparameters_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xstatus_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xutil_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xutil__memtest_8c.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xversion_8c.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/doc/html/api/xversion_8h.html delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/Makefile delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xbasic_types.c delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xbasic_types.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xenv.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xenv_linux.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xenv_none.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xenv_standalone.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xenv_vxworks.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xparameters.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xstatus.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xutil.h delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xutil_memtest.c delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xversion.c delete mode 100644 thirdparty/libxil/orig/common_v1_00_a/src/xversion.h delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/data/hls_dft.mdd delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/data/hls_dft.tcl delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/src/Makefile delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/src/xhls_dft.c delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/src/xhls_dft.h delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/src/xhls_dft_hw.h delete mode 100644 thirdparty/libxil/orig/hls_dft_v1_0/src/xhls_dft_sinit.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/data/intc.mdd delete mode 100644 thirdparty/libxil/orig/intc_v3_4/data/intc.tcl delete mode 100644 thirdparty/libxil/orig/intc_v3_4/data/intc_header.h delete mode 100644 thirdparty/libxil/orig/intc_v3_4/data/intc_tapp.tcl delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/functions.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/functions_vars.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/globals_vars.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/group__intc__v3__4.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/struct_x_intc.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/struct_x_intc___config.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc_8h.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__g_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__i_8h.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__intr_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__l_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__l_8h.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__options_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xintc__selftest_8c.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/intc_v3_4/examples/index.html delete mode 100644 thirdparty/libxil/orig/intc_v3_4/examples/xintc_example.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/examples/xintc_low_level_example.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/examples/xintc_tapp_example.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/Makefile delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc.h delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_g.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_i.h delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_intr.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_l.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_l.h delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_options.c delete mode 100644 thirdparty/libxil/orig/intc_v3_4/src/xintc_selftest.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/data/llfifo.mdd delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/data/llfifo.tcl delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/functions.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/functions_vars.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/globals_type.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/group__llfifo__v5__0.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/struct_x_ll_fifo.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/struct_x_strm___rx_fifo_streamer.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/struct_x_strm___tx_fifo_streamer.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/xllfifo_8c.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/xllfifo_8h.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/xllfifo__hw_8h.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/examples/index.html delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/examples/xllfifo_interrupt_example.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/examples/xllfifo_polling_example.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/Makefile delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xllfifo.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xllfifo.h delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xllfifo_g.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xllfifo_hw.h delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xllfifo_sinit.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xstreamer.c delete mode 100644 thirdparty/libxil/orig/llfifo_v5_0/src/xstreamer.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/data/tmrctr.mdd delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/data/tmrctr.tcl delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/data/tmrctr_header.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/data/tmrctr_intr_header.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/data/tmrctr_tapp.tcl delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/HTML_custom.css delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/annotated.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/classes.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/doc.png delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/dynsections.js delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/files.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/functions.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/functions_vars.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/globals.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/globals_defs.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/globals_func.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/globals_type.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/globals_vars.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/group__tmrctr__v3__0.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/group__tmrctr__v4__0.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/index.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/jquery.js delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/modules.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/struct_x_tmr_ctr.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/struct_x_tmr_ctr___config.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/struct_x_tmr_ctr_stats.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/tab_a.png delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/tab_b.png delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/tab_h.png delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/tab_s.png delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/tabs.css delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xlogo_bg.gif delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr_8h.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__g_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__i_8h.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__intr_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__l_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__l_8h.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__options_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__selftest_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__sinit_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/doc/html/api/xtmrctr__stats_8c.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/index.html delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_fast_intr_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_intr_64bit_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_intr_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_low_level_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_polled_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/examples/xtmrctr_selftest_example.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/Makefile delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_g.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_i.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_intr.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_l.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_l.h delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_options.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_selftest.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_sinit.c delete mode 100644 thirdparty/libxil/orig/tmrctr_v4_0/src/xtmrctr_stats.c delete mode 100644 thirdparty/libxil/src/xil_io.c diff --git a/.gitmodules b/.gitmodules index 79fac9332..551d2b3ff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "thirdparty/libcurl"] path = thirdparty/libcurl url = https://github.com/curl/curl.git +[submodule "thirdparty/libxil"] + path = thirdparty/libxil + url = git@git.rwth-aachen.de:VILLASframework/libxil.git diff --git a/thirdparty/libxil b/thirdparty/libxil new file mode 160000 index 000000000..a5be201b5 --- /dev/null +++ b/thirdparty/libxil @@ -0,0 +1 @@ +Subproject commit a5be201b5992ecd1c37835634323e1a871a18705 diff --git a/thirdparty/libxil/.gitignore b/thirdparty/libxil/.gitignore deleted file mode 100644 index c038681dc..000000000 --- a/thirdparty/libxil/.gitignore +++ /dev/null @@ -1 +0,0 @@ -libxil.so \ No newline at end of file diff --git a/thirdparty/libxil/CMakeLists.txt b/thirdparty/libxil/CMakeLists.txt deleted file mode 100644 index f710497e5..000000000 --- a/thirdparty/libxil/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required (VERSION 3.2) - -project(libxil C) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fPIC -I$(SRCDIR)/include/xilinx -Iorig/common_v1_00_a/src -Wno-int-conversion -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast") - -file(GLOB SOURCES src/*.c orig/*/src/*.c) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/xilinx) - -add_library(xil SHARED ${SOURCES}) - -include(FindPkgConfig QUIET) -if(PKG_CONFIG_FOUND) - # convert lists of link libraries into -lstdc++ -lm etc.. - foreach(LIB ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES} ${PLATFORM_LIBS}) - set(PRIVATE_LIBS "${PRIVATE_LIBS} -l${LIB}") - endforeach() - - # Produce a pkg-config file for linking against the shared lib - configure_file("libxil.pc.in" "libxil.pc" @ONLY) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libxil.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig") -endif() - -install(TARGETS xil DESTINATION lib) - -file(GLOB HEADERS include/xilinx/*.h) - -# Make sure we dont install symlinks -set (HEADERS_RESOLVED "") -foreach (HEADER ${HEADERS}) - get_filename_component(HEADER_RESOLVED "${HEADER}" REALPATH) - list (APPEND HEADERS_RESOLVED "${HEADER_RESOLVED}") -endforeach() - -install(FILES ${HEADERS_RESOLVED} DESTINATION include/xilinx) \ No newline at end of file diff --git a/thirdparty/libxil/README.md b/thirdparty/libxil/README.md deleted file mode 100644 index c42363e74..000000000 --- a/thirdparty/libxil/README.md +++ /dev/null @@ -1 +0,0 @@ -These drivers are taken from https://github.com/Xilinx/embeddedsw/tree/master/XilinxProcessorIPLib/drivers \ No newline at end of file diff --git a/thirdparty/libxil/include/xilinx/xaxidma.h b/thirdparty/libxil/include/xilinx/xaxidma.h deleted file mode 100644 index 86f62dd65..000000000 --- a/thirdparty/libxil/include/xilinx/xaxidma.h +++ /dev/null @@ -1,741 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xaxidma.h -* @addtogroup axidma_v9_0 -* @{ -* @details -* -* This is the driver API for the AXI DMA engine. -* -* For a full description of DMA features, please see the hardware spec. This -* driver supports the following features: -* -* - Scatter-Gather DMA (SGDMA) -* - Simple DMA -* - Interrupts -* - Programmable interrupt coalescing for SGDMA -* - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA -* engine -* -* Simple DMA -* -* Simple DMA allows the application to define a single transaction between DMA -* and Device. It has two channels: one from the DMA to Device and the other -* from Device to DMA. Application has to set the buffer address and -* length fields to initiate the transfer in respective channel. -* -* Transactions -* -* The object used to describe a transaction is referred to as a Buffer -* Descriptor (BD). Buffer descriptors are allocated in the user application. -* The user application needs to set buffer address, transfer length, and -* control information for this transfer. The control information includes -* SOF and EOF. Definition of those masks are in xaxidma_hw.h -* -* Scatter-Gather DMA -* -* SGDMA allows the application to define a list of transactions in memory which -* the hardware will process without further application intervention. During -* this time, the application is free to continue adding more work to keep the -* Hardware busy. -* -* User can check for the completion of transactions through polling the -* hardware, or interrupts. -* -* SGDMA processes whole packets. A packet is defined as a series of -* data bytes that represent a message. SGDMA allows a packet of data to be -* broken up into one or more transactions. For example, take an Ethernet IP -* packet which consists of a 14 byte header followed by a 1 or more bytes of -* payload. With SGDMA, the application may point a BD to the header and another -* BD to the payload, then transfer them as a single message. This strategy can -* make a TCP/IP stack more efficient by allowing it to keep packet header and -* data in different memory regions instead of assembling packets into -* contiguous blocks of memory. -* -* BD Ring Management -* -* BD rings are shared by the software and the hardware. -* -* The hardware expects BDs to be setup as a linked list. The DMA hardware walks -* through the list by following the next pointer field of a completed BD. -* The hardware stops processing when the just completed BD is the same as the -* BD specified in the Tail Ptr register in the hardware. -* -* The last BD in the ring is linked to the first BD in the ring. -* -* All BD management are done inside the driver. The user application should not -* directly modify the BD fields. Modifications to the BD fields should always -* go through the specific API functions. -* -* Within the ring, the driver maintains four groups of BDs. Each group consists -* of 0 or more adjacent BDs: -* -* - Free: The BDs that can be allocated by the application with -* XAxiDma_BdRingAlloc(). -* -* - Pre-process: The BDs that have been allocated with -* XAxiDma_BdRingAlloc(). These BDs are under application control. The -* application modifies these BDs through driver API to prepare them -* for DMA transactions. -* -* - Hardware: The BDs that have been enqueued to hardware with -* XAxiDma_BdRingToHw(). These BDs are under hardware control and may be in a -* state of awaiting hardware processing, in process, or processed by -* hardware. It is considered an error for the application to change BDs -* while they are in this group. Doing so can cause data corruption and lead -* to system instability. -* -* - Post-process: The BDs that have been processed by hardware and have -* been extracted from the Hardware group with XAxiDma_BdRingFromHw(). -* These BDs are under application control. The application can check the -* transfer status of these BDs. The application use XAxiDma_BdRingFree() -* to put them into the Free group. -* -* BDs are expected to transition in the following way for continuous -* DMA transfers: -*
-*
-*         XAxiDma_BdRingAlloc()                   XAxiDma_BdRingToHw()
-*   Free ------------------------> Pre-process ----------------------> Hardware
-*                                                                      |
-*    /|\                                                               |
-*     |   XAxiDma_BdRingFree()                  XAxiDma_BdRingFromHw() |
-*     +--------------------------- Post-process <----------------------+
-*
-* 
-* -* When a DMA transfer is to be cancelled before enqueuing to hardware, -* application can return the requested BDs to the Free group using -* XAxiDma_BdRingUnAlloc(), as shown below: -*
-*
-*         XAxiDma_BdRingUnAlloc()
-*   Free <----------------------- Pre-process
-*
-* 
-* -* The API provides functions for BD list traversal: -* - XAxiDma_BdRingNext() -* - XAxiDma_BdRingPrev() -* -* These functions should be used with care as they do not understand where -* one group ends and another begins. -* -* SGDMA Descriptor Ring Creation -* -* BD ring is created using XAxiDma_BdRingCreate(). The memory for the BD ring -* is allocated by the application, and it has to be contiguous. Physical -* address is required to setup the BD ring. -* -* The applicaiton can use XAxiDma_BdRingMemCalc() to find out the amount of -* memory needed for a certain number of BDs. XAxiDma_BdRingCntCalc() can be -* used to find out how many BDs can be allocated for certain amount of memory. -* -* A helper function, XAxiDma_BdRingClone(), can speed up the BD ring setup if -* the BDs have same types of controls, for example, SOF and EOF. After -* using the XAxiDma_BdRingClone(), the application only needs to setup the -* buffer address and transfer length. Note that certain BDs in one packet, -* for example, the first BD and the last BD, may need to setup special -* control information. -* -* Descriptor Ring State Machine -* -* There are two states of the BD ring: -* -* - HALTED (H), where hardware is not running -* -* - NOT HALTED (NH), where hardware is running -* -* The following diagram shows the state transition for the DMA engine: -* -*
-*   _____ XAxiDma_StartBdRingHw(), or XAxiDma_BdRingStart(),   ______
-*   |   |               or XAxiDma_Resume()                    |    |
-*   | H |----------------------------------------------------->| NH |
-*   |   |<-----------------------------------------------------|    |
-*   -----   XAxiDma_Pause() or XAxiDma_Reset()                 ------
-* 
-* -* Interrupt Coalescing -* -* SGDMA provides control over the frequency of interrupts through interrupt -* coalescing. The DMA engine provides two ways to tune the interrupt -* coalescing: -* -* - The packet threshold counter. Interrupt will fire once the -* programmable number of packets have been processed by the engine. -* -* - The packet delay timer counter. Interrupt will fire once the -* programmable amount of time has passed after processing the last packet, -* and no new packets to process. Note that the interrupt will only fire if -* at least one packet has been processed. -* -* Interrupt -* -* Interrupts are handled by the user application. Each DMA channel has its own -* interrupt ID. The driver provides APIs to enable/disable interrupt, -* and tune the interrupt frequency regarding to packet processing frequency. -* -* Software Initialization -* -* -* To use the Simple mode DMA engine for transfers, the following setup is -* required: -* -* - DMA Initialization using XAxiDma_CfgInitialize() function. This step -* initializes a driver instance for the given DMA engine and resets the -* engine. -* -* - Enable interrupts if chosen to use interrupt mode. The application is -* responsible for setting up the interrupt system, which includes providing -* and connecting interrupt handlers and call back functions, before -* enabling the interrupts. -* -* - Set the buffer address and length field in respective channels to start -* the DMA transfer -* -* To use the SG mode DMA engine for transfers, the following setup are -* required: -* -* - DMA Initialization using XAxiDma_CfgInitialize() function. This step -* initializes a driver instance for the given DMA engine and resets the -* engine. -* -* - BD Ring creation. A BD ring is needed per DMA channel and can be built by -* calling XAxiDma_BdRingCreate(). -* -* - Enable interrupts if chose to use interrupt mode. The application is -* responsible for setting up the interrupt system, which includes providing -* and connecting interrupt handlers and call back functions, before -* enabling the interrupts. -* -* - Start a DMA transfer: Call XAxiDma_BdRingStart() to start a transfer for -* the first time or after a reset, and XAxiDma_BdRingToHw() if the channel -* is already started. Calling XAxiDma_BdRingToHw() when a DMA channel is not -* running will not put the BDs to the hardware, and the BDs will be processed -* later when the DMA channel is started through XAxiDma_BdRingStart(). -* -* How to start DMA transactions -* -* The user application uses XAxiDma_BdRingToHw() to submit BDs to the hardware -* to start DMA transfers. -* -* For both channels, if the DMA engine is currently stopped (using -* XAxiDma_Pause()), the newly added BDs will be accepted but not processed -* until the DMA engine is started, using XAxiDma_BdRingStart(), or resumed, -* using XAxiDma_Resume(). -* -* Software Post-Processing on completed DMA transactions -* -* If the interrupt system has been set up and the interrupts are enabled, -* a DMA channels notifies the software about the completion of a transfer -* through interrupts. Otherwise, the user application can poll for -* completions of the BDs, using XAxiDma_BdRingFromHw() or -* XAxiDma_BdHwCompleted(). -* -* - Once BDs are finished by a channel, the application first needs to fetch -* them from the channel using XAxiDma_BdRingFromHw(). -* -* - On the TX side, the application now could free the data buffers attached to -* those BDs as the data in the buffers has been transmitted. -* -* - On the RX side, the application now could use the received data in the -* buffers attached to those BDs. -* -* - For both channels, completed BDs need to be put back to the Free group -* using XAxiDma_BdRingFree(), so they can be used for future transactions. -* -* - On the RX side, it is the application's responsibility to have BDs ready -* to receive data at any time. Otherwise, the RX channel refuses to -* accept any data if it has no RX BDs. -* -* Examples -* -* We provide five examples to show how to use the driver API: -* - One for SG interrupt mode (xaxidma_example_sg_intr.c), multiple BD/packets transfer -* - One for SG polling mode (xaxidma_example_sg_poll.c), single BD transfer. -* - One for SG polling mode (xaxidma_poll_multi_pkts.c), multiple BD/packets transfer -* - One for simple polling mode (xaxidma_example_simple_poll.c) -* - One for simple Interrupt mode (xaxidma_example_simple_intr.c) -* -* Address Translation -* -* All buffer addresses and BD addresses for the hardware are physical -* addresses. The user application is responsible to provide physical buffer -* address for the BD upon BD ring creation. The user application accesses BD -* through its virtual addess. The driver maintains the address translation -* between the physical and virtual address for BDs. -* -* Cache Coherency -* -* This driver expects all application buffers attached to BDs to be in cache -* coherent memory. If cache is used in the system, buffers for transmit MUST -* be flushed from the cache before passing the associated BD to this driver. -* Buffers for receive MUST be invalidated before accessing the data. -* -* Alignment -* -* For BDs: -* -* Minimum alignment is defined by the constant XAXIDMA_BD_MINIMUM_ALIGNMENT. -* This is the smallest alignment allowed by both hardware and software for them -* to properly work. -* -* If the descriptor ring is to be placed in cached memory, alignment also MUST -* be at least the processor's cache-line size. Otherwise, system instability -* occurs. For alignment larger than the cache line size, multiple cache line -* size alignment is required. -* -* Aside from the initial creation of the descriptor ring (see -* XAxiDma_BdRingCreate()), there are no other run-time checks for proper -* alignment of BDs. -* -* For application data buffers: -* -* Application data buffers may reside on any alignment if DRE is built into the -* hardware. Otherwise, application data buffer must be word-aligned. The word -* is defined by XPAR_AXIDMA_0_M_AXIS_MM2S_TDATA_WIDTH for transmit and -* XPAR_AXIDMA_0_S_AXIS_S2MM_TDATA_WIDTH for receive. -* -* For scatter gather transfers that have more than one BDs in the chain of BDs, -* Each BD transfer length must be multiple of word too. Otherwise, internal -* error happens in the hardware. -* -* Error Handling -* -* The DMA engine will halt on all error conditions. It requires the software -* to do a reset before it can start process new transfer requests. -* -* Restart After Stopping -* -* After the DMA engine has been stopped (through reset or reset after an error) -* the software keeps track of the current BD pointer when reset happens, and -* processing of BDs can be resumed through XAxiDma_BdRingStart(). -* -* Limitations -* -* This driver does not have any mechanisms for mutual exclusion. It is up to -* the application to provide this protection. -* -* Hardware Defaults & Exclusive Use -* -* After the initialization or reset, the DMA engine is in the following -* default mode: -* - All interrupts are disabled. -* -* - Interrupt coalescing counter is 1. -* -* - The DMA engine is not running (halted). Each DMA channel is started -* separately, using XAxiDma_StartBdRingHw() if no BDs are setup for transfer -* yet, or XAxiDma_BdRingStart() otherwise. -* -* The driver has exclusive use of the registers and BDs. All accesses to the -* registers and BDs should go through the driver interface. -* -* Debug Print -* -* To see the debug print for the driver, please put "-DDEBUG" as the extra -* compiler flags in software platform settings. Also comment out the line in -* xdebug.h: "#undef DEBUG". -* -* Changes From v1.00a -* -* . We have changes return type for XAxiDma_BdSetBufAddr() from void to int -* . We added XAxiDma_LookupConfig() so that user does not need to look for the -* hardware settings anymore. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a jz   05/18/10 First release
-* 2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
-*                     updated tcl file, added xaxidma_porting_guide.h
-* 3.00a jz   11/22/10 Support IP core parameters change
-* 4.00a rkv  02/22/11 Added support for simple DMA mode
-*		      New API added for simple DMA mode are
-*			- XAxiDma_Busy
-*			- XAxiDma_SimpleTransfer
-*		      New Macros added for simple DMA mode are
-* 			- XAxiDma_HasSg
-* 			- XAxiDma_IntrEnable
-* 			- XAxiDma_IntrGetEnabled
-* 			- XAxiDma_IntrDisable
-* 			- XAxiDma_IntrGetIrq
-* 			- XAxiDma_IntrAckIrq
-* 5.00a srt  08/25/11  Added support for memory barrier and modified
-*			Cache Macros to have a common API for Microblaze
-*			and Zynq.
-* 6.00a srt  01/24/12 Added support for Multi-Channel DMA mode.
-*		      - Changed APIs:
-*			* XAxiDma_GetRxRing(InstancePtr, RingIndex)
-*			* XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex)
-*			* XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex)
-*			* XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex)
-*			* XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex)
-*			* XAxiDma_SimpleTransfer(XAxiDma *InstancePtr,
-*        					u32 BuffAddr, u32 Length,
-*						int Direction, int RingIndex)
-*			* XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
-*					int RingIndex)
-*			* XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-*			* XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
-*        			int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
-*			* XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-*			* XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-*			* XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr,
-*					u32 LenBytes, u32 LengthMask)
-*       		* XAxiDma_BdGetActualLength(BdPtr, LengthMask)
-*			* XAxiDma_BdGetLength(BdPtr, LengthMask)
-*		       - New APIs
-*			* XAxiDma_SelectKeyHole(XAxiDma *InstancePtr,
-*						int Direction, int Select)
-*			* XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr,
-*						int RingIndex)
-* 7.00a srt  06/18/12  All the APIs changed in v6_00_a are reverted back for
-*		       backward compatibility.
-*			- New API:
-*			  XAxiDma_GetRxIndexRing(InstancePtr, RingIndex)
-* 7.01a srt  10/26/12  - Fixed issue with driver as it fails with IP version
-*		         < 6.00a as the parameter C_NUM_*_CHANNELS is not
-*			 applicable.
-*		       - Changed the logic of MCDMA BD fields Set APIs, to
-*			 clear the field first and then set it.
-* 7.02a srt  01/23/13  Replaced *_TDATA_WIDTH parameters to *_DATA_WIDTH
-*		       (CR 691867)
-*		       Updated DDR base address for IPI designs (CR 703656).
-* 8.0   adk  19/12/13  Updated as per the New Tcl API's
-*	srt  01/29/14  Added support for Micro DMA Mode and cyclic mode of
-*		       operations.
-*		      - New APIs:
-*			* XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr,
-*						int Direction, int Select)
- *			* XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd*, u32)
-* 8.1   adk  20/01/15  Added support for peripheral test. Created the self
-*		       test example to include it on peripheral test's(CR#823144).
-* 8.1   adk  29/01/15  Added the sefltest api (XAxiDma_Selftest) to the driver source files
-* 		      (xaxidma_selftest.c) and called this from the selftest example
-* 9.0 	adk  27/07/15  Added support for 64-bit Addressing.
-* 9.0   adk  19/08/15  Fixed CR#873125 DMA SG Mode example tests are failing on
-*		       HW in 2015.3.
-*
-* 
-* -******************************************************************************/ - -#ifndef XAXIDMA_H_ /* prevent circular inclusions */ -#define XAXIDMA_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ -#include "xaxidma_bdring.h" -#ifdef __MICROBLAZE__ -#include "xenv.h" -#else -#include -#include "xil_cache.h" -#endif - -/************************** Constant Definitions *****************************/ - - -/**************************** Type Definitions *******************************/ - -/** - * The XAxiDma driver instance data. An instance must be allocated for each DMA - * engine in use. - */ -typedef struct XAxiDma { - u32 RegBase; /* Virtual base address of DMA engine */ - - int HasMm2S; /* Has transmit channel */ - int HasS2Mm; /* Has receive channel */ - int Initialized; /* Driver has been initialized */ - int HasSg; - - XAxiDma_BdRing TxBdRing; /* BD container management for TX channel */ - XAxiDma_BdRing RxBdRing[16]; /* BD container management for RX channel */ - int TxNumChannels; - int RxNumChannels; - int MicroDmaMode; - int AddrWidth; /**< Address Width */ -} XAxiDma; - -/** - * The configuration structure for AXI DMA engine - * - * This structure passes the hardware building information to the driver - */ -typedef struct { - u32 DeviceId; - u32 BaseAddr; - - int HasStsCntrlStrm; - int HasMm2S; - int HasMm2SDRE; - int Mm2SDataWidth; - int HasS2Mm; - int HasS2MmDRE; - int S2MmDataWidth; - int HasSg; - int Mm2sNumChannels; - int S2MmNumChannels; - int Mm2SBurstSize; - int S2MmBurstSize; - int MicroDmaMode; - int AddrWidth; /**< Address Width */ -} XAxiDma_Config; - - -/***************** Macros (Inline Functions) Definitions *********************/ -/*****************************************************************************/ -/** -* Get Transmit (Tx) Ring ptr -* -* Warning: This has a different API than the LLDMA driver. It now returns -* the pointer to the BD ring. -* -* @param InstancePtr is a pointer to the DMA engine instance to be -* worked on. -* -* @return Pointer to the Tx Ring -* -* @note C-style signature: -* XAxiDma_BdRing * XAxiDma_GetTxRing(XAxiDma * InstancePtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_GetTxRing(InstancePtr) \ - (&((InstancePtr)->TxBdRing)) - -/*****************************************************************************/ -/** -* Get Receive (Rx) Ring ptr -* -* Warning: This has a different API than the LLDMA driver. It now returns -* the pointer to the BD ring. -* -* @param InstancePtr is a pointer to the DMA engine instance to be -* worked on. -* -* @return Pointer to the Rx Ring -* -* @note -* C-style signature: -* XAxiDma_BdRing * XAxiDma_GetRxRing(XAxiDma * InstancePtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_GetRxRing(InstancePtr) \ - (&((InstancePtr)->RxBdRing[0])) - -/*****************************************************************************/ -/** -* Get Receive (Rx) Ring ptr of a Index -* -* Warning: This has a different API than the LLDMA driver. It now returns -* the pointer to the BD ring. -* -* @param InstancePtr is a pointer to the DMA engine instance to be -* worked on. -* @param RingIndex is the channel Index. -* -* @return Pointer to the Rx Ring -* -* @note -* C-style signature: -* XAxiDma_BdRing * XAxiDma_GetRxIndexRing(XAxiDma * InstancePtr, - int RingIndex) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_GetRxIndexRing(InstancePtr, RingIndex) \ - (&((InstancePtr)->RxBdRing[RingIndex])) - -/*****************************************************************************/ -/** -* This function checks whether system is configured as Simple or -* Scatter Gather mode -* -* @param InstancePtr is a pointer to the DMA engine instance to be -* worked on. -* -* @return -* - TRUE if configured as SG mode -* - FALSE if configured as simple mode -* -* @note None -* -*****************************************************************************/ -#define XAxiDma_HasSg(InstancePtr) ((InstancePtr)->HasSg) ? TRUE : FALSE - -/*****************************************************************************/ -/** - * This function enables interrupts specified by the Mask in specified - * direction, Interrupts that are not in the mask are not affected. - * - * @param InstancePtr is the driver instance we are working on - * @param Mask is the mask for the interrupts to be enabled - * @param Direction is DMA transfer direction, valid values are - * - XAXIDMA_DMA_TO_DEVICE. - * - XAXIDMA_DEVICE_TO_DMA. - * @return None - * - * @note None - * - *****************************************************************************/ -#define XAxiDma_IntrEnable(InstancePtr, Mask, Direction) \ - XAxiDma_WriteReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET, \ - (XAxiDma_ReadReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET)) \ - | (Mask & XAXIDMA_IRQ_ALL_MASK)) - - -/*****************************************************************************/ -/** - * This function gets the mask for the interrupts that are currently enabled - * - * @param InstancePtr is the driver instance we are working on - * @param Direction is DMA transfer direction, valid values are - * - XAXIDMA_DMA_TO_DEVICE. - * - XAXIDMA_DEVICE_TO_DMA. - * - * @return The bit mask for the interrupts that are currently enabled - * - * @note None - * - *****************************************************************************/ -#define XAxiDma_IntrGetEnabled(InstancePtr, Direction) \ - XAxiDma_ReadReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET) &\ - XAXIDMA_IRQ_ALL_MASK) - - - -/*****************************************************************************/ -/** - * This function disables interrupts specified by the Mask. Interrupts that - * are not in the mask are not affected. - * - * @param InstancePtr is the driver instance we are working on - * @param Mask is the mask for the interrupts to be disabled - * @param Direction is DMA transfer direction, valid values are - * - XAXIDMA_DMA_TO_DEVICE. - * - XAXIDMA_DEVICE_TO_DMA. - * @return None - * - * @note None - * - *****************************************************************************/ - #define XAxiDma_IntrDisable(InstancePtr, Mask, Direction) \ - XAxiDma_WriteReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET, \ - (XAxiDma_ReadReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET)) \ - & ~(Mask & XAXIDMA_IRQ_ALL_MASK)) - - -/*****************************************************************************/ -/** - * This function gets the interrupts that are asserted. - * - * @param InstancePtr is the driver instance we are working on - * @param Direction is DMA transfer direction, valid values are - * - XAXIDMA_DMA_TO_DEVICE. - * - XAXIDMA_DEVICE_TO_DMA. - * - * @return The bit mask for the interrupts asserted. - * - * @note None - * - *****************************************************************************/ -#define XAxiDma_IntrGetIrq(InstancePtr, Direction) \ - (XAxiDma_ReadReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_SR_OFFSET) &\ - XAXIDMA_IRQ_ALL_MASK) - -/*****************************************************************************/ -/** - * This function acknowledges the interrupts that are specified in Mask - * - * @param InstancePtr is the driver instance we are working on - * @param Mask is the mask for the interrupts to be acknowledge - * @param Direction is DMA transfer direction, valid values are - * - XAXIDMA_DMA_TO_DEVICE. - * - XAXIDMA_DEVICE_TO_DMA. - * - * @return None - * - * @note None. - * - *****************************************************************************/ -#define XAxiDma_IntrAckIrq(InstancePtr, Mask, Direction) \ - XAxiDma_WriteReg((InstancePtr)->RegBase + \ - (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_SR_OFFSET, \ - (Mask) & XAXIDMA_IRQ_ALL_MASK) - - - -/************************** Function Prototypes ******************************/ - -/* - * Initialization and control functions in xaxidma.c - */ -XAxiDma_Config *XAxiDma_LookupConfig(u32 DeviceId); -int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config); -void XAxiDma_Reset(XAxiDma * InstancePtr); -int XAxiDma_ResetIsDone(XAxiDma * InstancePtr); -int XAxiDma_Pause(XAxiDma * InstancePtr); -int XAxiDma_Resume(XAxiDma * InstancePtr); -u32 XAxiDma_Busy(XAxiDma *InstancePtr,int Direction); -u32 XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, UINTPTR BuffAddr, u32 Length, - int Direction); -int XAxiDma_SelectKeyHole(XAxiDma *InstancePtr, int Direction, int Select); -int XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr, int Direction, int Select); -int XAxiDma_Selftest(XAxiDma * InstancePtr); -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxidma_bd.h b/thirdparty/libxil/include/xilinx/xaxidma_bd.h deleted file mode 100644 index 0b8879ce1..000000000 --- a/thirdparty/libxil/include/xilinx/xaxidma_bd.h +++ /dev/null @@ -1,679 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** - * - * @file xaxidma_bd.h -* @addtogroup axidma_v9_0 -* @{ - * - * Buffer descriptor (BD) management API. - * - * Buffer Descriptors - * - * A BD defines a DMA transaction (see "Transaction" section in xaxidma.h). - * All accesses to a BD go through this set of API. - * - * The XAxiDma_Bd structure defines a BD. The first XAXIDMA_BD_HW_NUM_BYTES - * are shared between hardware and software. - * - * Actual Transfer Length - * - * The actual transfer length for receive could be smaller than the requested - * transfer length. The hardware sets the actual transfer length in the - * completed BD. The API to retrieve the actual transfer length is - * XAxiDma_GetActualLength(). - * - * User IP words - * - * There are 5 user IP words in each BD. - * - * If hardware does not have the StsCntrl stream built in, then these words - * are not usable. Retrieving these words get a NULL pointer and setting - * these words results an error. - * - * Performance - * - * BDs are typically in a non-cached memory space. Reducing the number of - * I/O operations to BDs can improve overall performance of the DMA channel. - * - *
- * MODIFICATION HISTORY:
- *
- * Ver   Who  Date     Changes
- * ----- ---- -------- ------------------------------------------------------
- * 1.00a jz   05/18/10 First release
- * 2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
- *                     updated tcl file, added xaxidma_porting_guide.h
- * 3.00a jz   11/22/10 Support IP core parameters change
- * 5.00a srt  08/25/11 Changed Cache Macros to have a common API for Zynq
- *		           and Microblaze.
- * 6.00a srt  01/24/12 Added APIs to support Multi-Channel DMA:
- *			XAxiDma_BdSetTId()
- *			XAxiDma_BdGetTId()
- *			XAxiDma_BdSetTDest()
- *			XAxiDma_BdGetTDest()
- *			XAxiDma_BdSetTUser()
- *			XAxiDma_BdGetTUser()
- *			XAxiDma_BdSetARCache()
- *			XAxiDma_BdGetARCache()
- *			XAxiDma_BdSetARUser()
- *			XAxiDma_BdGetARUser()
- *			XAxiDma_BdSetStride()
- *			XAxiDma_BdGetStride()
- *			XAxiDma_BdSetVSize()
- *			XAxiDma_BdGetVSize()
- *			- Changed APIs
- *			XAxiDma_BdGetActualLength(BdPtr, LengthMask)
- *			XAxiDma_BdGetLength(BdPtr, LengthMask)
- *			XAxiDma_BdSetLength(XAxiDma_Bd* BdPtr,
- *					u32 LenBytes, u32 LengthMask)
- * 7.01a srt  10/26/12  Changed the logic of MCDMA BD fields Set APIs, to
- *			clear the field first and set it.
- * 8.0   srt  01/29/14 Added support for Micro DMA Mode.
- *
- * 
- *****************************************************************************/ - -#ifndef XAXIDMA_BD_H_ /* To prevent circular inclusions */ -#define XAXIDMA_BD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xaxidma_hw.h" -#include "xstatus.h" -#include "xdebug.h" -#include "xil_cache.h" - -#ifdef __MICROBLAZE__ -#include "xenv.h" -#else -#include -#endif - -/************************** Constant Definitions *****************************/ - -/**************************** Type Definitions *******************************/ - -/** - * The XAxiDma_Bd is the type for a buffer descriptor (BD). - */ - -typedef UINTPTR XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS]; - - -/***************** Macros (Inline Functions) Definitions *********************/ - -/****************************************************************************** - * Define methods to flush and invalidate cache for BDs should they be - * located in cached memory. - *****************************************************************************/ -#ifdef __aarch64__ -#define XAXIDMA_CACHE_FLUSH(BdPtr) -#define XAXIDMA_CACHE_INVALIDATE(BdPtr) -#else -#define XAXIDMA_CACHE_FLUSH(BdPtr) \ - Xil_DCacheFlushRange((UINTPTR)(BdPtr), XAXIDMA_BD_HW_NUM_BYTES) - -#define XAXIDMA_CACHE_INVALIDATE(BdPtr) \ - Xil_DCacheInvalidateRange((UINTPTR)(BdPtr), XAXIDMA_BD_HW_NUM_BYTES) -#endif - -/*****************************************************************************/ -/** -* -* Read the given Buffer Descriptor word. -* -* @param BaseAddress is the base address of the BD to read -* @param Offset is the word offset to be read -* -* @return The 32-bit value of the field -* -* @note -* C-style signature: -* u32 XAxiDma_BdRead(u32 BaseAddress, u32 Offset) -* -******************************************************************************/ -#define XAxiDma_BdRead(BaseAddress, Offset) \ - (*(u32 *)((UINTPTR)((void *)(BaseAddress)) + (u32)(Offset))) - -/*****************************************************************************/ -/** -* -* Write the given Buffer Descriptor word. -* -* @param BaseAddress is the base address of the BD to write -* @param Offset is the word offset to be written -* @param Data is the 32-bit value to write to the field -* -* @return None. -* -* @note -* C-style signature: -* void XAxiDma_BdWrite(u32 BaseAddress, u32 RegOffset, u32 Data) -* -******************************************************************************/ -#define XAxiDma_BdWrite(BaseAddress, Offset, Data) \ - (*(u32 *)((UINTPTR)(void *)(BaseAddress) + (u32)(Offset))) = (u32)(Data) - -/*****************************************************************************/ -/** - * Zero out BD specific fields. BD fields that are for the BD ring or for the - * system hardware build information are not touched. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdClear(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdClear(BdPtr) \ - memset((void *)(((UINTPTR)(BdPtr)) + XAXIDMA_BD_START_CLEAR), 0, \ - XAXIDMA_BD_BYTES_TO_CLEAR) - -/*****************************************************************************/ -/** - * Get the control bits for the BD - * - * @param BdPtr is the BD to operate on - * - * @return The bit mask for the control of the BD - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetCtrl(BdPtr) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) \ - & XAXIDMA_BD_CTRL_ALL_MASK) -/*****************************************************************************/ -/** - * Retrieve the status of a BD - * - * @param BdPtr is the BD to operate on - * - * @return Word at offset XAXIDMA_BD_DMASR_OFFSET. Use XAXIDMA_BD_STS_*** - * values defined in xaxidma_hw.h to interpret the returned value - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetSts(BdPtr) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \ - XAXIDMA_BD_STS_ALL_MASK) -/*****************************************************************************/ -/** - * Retrieve the length field value from the given BD. The returned value is - * the same as what was written with XAxiDma_BdSetLength(). Note that in the - * this value does not reflect the real length of received data. - * See the comments of XAxiDma_BdSetLength() for more details. To obtain the - * actual transfer length, use XAxiDma_BdGetActualLength(). - * - * @param BdPtr is the BD to operate on. - * @param LengthMask is the Maximum Transfer Length. - * - * @return The length value set in the BD. - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetLength(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetLength(BdPtr, LengthMask) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_CTRL_LEN_OFFSET) & \ - LengthMask) - - -/*****************************************************************************/ -/** - * Set the ID field of the given BD. The ID is an arbitrary piece of data the - * application can associate with a specific BD. - * - * @param BdPtr is the BD to operate on - * @param Id is a 32 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetId(XAxiDma_Bd* BdPtr, void Id) - * - *****************************************************************************/ -#define XAxiDma_BdSetId(BdPtr, Id) \ - (XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_ID_OFFSET, (u32)(Id))) - - -/*****************************************************************************/ -/** - * Retrieve the ID field of the given BD previously set with XAxiDma_BdSetId. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetId(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetId(BdPtr) (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_ID_OFFSET)) - -/*****************************************************************************/ -/** - * Get the BD's buffer address - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetBufAddr(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetBufAddr(BdPtr) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_BUFA_OFFSET)) - -/*****************************************************************************/ -/** - * Check whether a BD has completed in hardware. This BD has been submitted - * to hardware. The application can use this function to poll for the - * completion of the BD. - * - * This function may not work if the BD is in cached memory. - * - * @param BdPtr is the BD to check on - * - * @return - * - 0 if not complete - * - XAXIDMA_BD_STS_COMPLETE_MASK if completed, may contain - * XAXIDMA_BD_STS_*_ERR_MASK bits. - * - * @note - * C-style signature: - * int XAxiDma_BdHwCompleted(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdHwCompleted(BdPtr) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \ - XAXIDMA_BD_STS_COMPLETE_MASK) - -/*****************************************************************************/ -/** - * Get the actual transfer length of a BD. The BD has completed in hw. - * - * This function may not work if the BD is in cached memory. - * - * @param BdPtr is the BD to check on - * @param LengthMask is the Maximum Transfer Length. - * - * @return None - * - * @note - * C-style signature: - * int XAxiDma_BdGetActualLength(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetActualLength(BdPtr, LengthMask) \ - (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET) & \ - LengthMask) - -/*****************************************************************************/ -/** - * Set the TID field of the TX BD. - * Provides a stream identifier and can be used to differentiate between - * multiple streams of data that are being transferred across the same - * interface. - * - * @param BdPtr is the BD to operate on - * @param TId is a 8 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetTId(XAxiDma_Bd* BdPtr, void TId) - * - *****************************************************************************/ -#define XAxiDma_BdSetTId(BdPtr, TId) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \ - ~XAXIDMA_BD_TID_FIELD_MASK); \ - val |= ((u32)(TId) << XAXIDMA_BD_TID_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the TID field of the RX BD previously set with XAxiDma_BdSetTId. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetTId(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetTId(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \ - XAXIDMA_BD_TID_FIELD_MASK) - -/*****************************************************************************/ -/** - * Set the TDEST field of the TX BD. - * Provides coarse routing information for the data stream. - * - * @param BdPtr is the BD to operate on - * @param TDest is a 8 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetTDest(XAxiDma_Bd* BdPtr, void TDest) - * - *****************************************************************************/ -#define XAxiDma_BdSetTDest(BdPtr, TDest) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \ - ~XAXIDMA_BD_TDEST_FIELD_MASK); \ - val |= ((u32)(TDest) << XAXIDMA_BD_TDEST_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the TDest field of the RX BD previously set with i - * XAxiDma_BdSetTDest. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetTDest(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetTDest(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \ - XAXIDMA_BD_TDEST_FIELD_MASK) - -/*****************************************************************************/ -/** - * Set the TUSER field of the TX BD. - * User defined sideband signaling. - * - * @param BdPtr is the BD to operate on - * @param TUser is a 8 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetTUser(XAxiDma_Bd* BdPtr, void TUser) - * - *****************************************************************************/ -#define XAxiDma_BdSetTUser(BdPtr, TUser) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \ - ~XAXIDMA_BD_TUSER_FIELD_MASK); \ - val |= ((u32)(TUser) << XAXIDMA_BD_TUSER_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the TUSER field of the RX BD previously set with - * XAxiDma_BdSetTUser. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetTUser(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetTUser(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STS_OFFSET)) & \ - XAXIDMA_BD_TUSER_FIELD_MASK) - -/*****************************************************************************/ -/** - * Set the ARCACHE field of the given BD. - * This signal provides additional information about the cacheable - * characteristics of the transfer. - * - * @param BdPtr is the BD to operate on - * @param ARCache is a 8 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetARCache(XAxiDma_Bd* BdPtr, void ARCache) - * - *****************************************************************************/ -#define XAxiDma_BdSetARCache(BdPtr, ARCache) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \ - ~XAXIDMA_BD_ARCACHE_FIELD_MASK); \ - val |= ((u32)(ARCache) << XAXIDMA_BD_ARCACHE_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the ARCACHE field of the given BD previously set with - * XAxiDma_BdSetARCache. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetARCache(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetARCache(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET)) & \ - XAXIDMA_BD_ARCACHE_FIELD_MASK) - - -/*****************************************************************************/ -/** - * Set the ARUSER field of the given BD. - * Sideband signals used for user defined information. - * - * @param BdPtr is the BD to operate on - * @param ARUser is a 8 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetARUser(XAxiDma_Bd* BdPtr, void ARUser) - * - *****************************************************************************/ -#define XAxiDma_BdSetARUser(BdPtr, ARUser) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET) & \ - ~XAXIDMA_BD_ARUSER_FIELD_MASK); \ - val |= ((u32)(ARUser) << XAXIDMA_BD_ARUSER_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_MCCTL_OFFSET, val); \ -} - - -/*****************************************************************************/ -/** - * Retrieve the ARUSER field of the given BD previously set with - * XAxiDma_BdSetARUser. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetARUser(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetARUser(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_MCCTL_OFFSET)) & \ - XAXIDMA_BD_ARUSER_FIELD_MASK) - -/*****************************************************************************/ -/** - * Set the STRIDE field of the given BD. - * It is the address distance between the first address of successive - * horizontal reads. - * - * @param BdPtr is the BD to operate on - * @param Stride is a 32 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetStride(XAxiDma_Bd* BdPtr, void Stride) - * - *****************************************************************************/ -#define XAxiDma_BdSetStride(BdPtr, Stride) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET) & \ - ~XAXIDMA_BD_STRIDE_FIELD_MASK); \ - val |= ((u32)(Stride) << XAXIDMA_BD_STRIDE_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the STRIDE field of the given BD previously set with - * XAxiDma_BdSetStride. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetStride(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetStride(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET)) & \ - XAXIDMA_BD_STRIDE_FIELD_MASK) - -/*****************************************************************************/ -/** - * Set the VSIZE field of the given BD. - * Number of horizontal lines for strided access. - * - * @param BdPtr is the BD to operate on - * @param VSize is a 32 bit quantity to set in the BD - * - * @return None - * - * @note - * C-style signature: - * void XAxiDma_BdSetVSize(XAxiDma_Bd* BdPtr, void VSize) - * - *****************************************************************************/ -#define XAxiDma_BdSetVSize(BdPtr, VSize) \ -{ \ - u32 val; \ - val = (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET) & \ - ~XAXIDMA_BD_VSIZE_FIELD_MASK); \ - val |= ((u32)(VSize) << XAXIDMA_BD_VSIZE_FIELD_SHIFT); \ - XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET, val); \ -} - -/*****************************************************************************/ -/** - * Retrieve the STRIDE field of the given BD previously set with - * XAxiDma_BdSetVSize. - * - * @param BdPtr is the BD to operate on - * - * @return None - * - * @note - * C-style signature: - * u32 XAxiDma_BdGetVSize(XAxiDma_Bd* BdPtr) - * - *****************************************************************************/ -#define XAxiDma_BdGetVSize(BdPtr) \ - ((XAxiDma_BdRead((BdPtr), XAXIDMA_BD_STRIDE_VSIZE_OFFSET)) & \ - XAXIDMA_BD_VSIZE_FIELD_MASK) - -/*****************************************************************************/ - -/************************** Function Prototypes ******************************/ - -int XAxiDma_BdSetLength(XAxiDma_Bd* BdPtr, u32 LenBytes, u32 LengthMask); -u32 XAxiDma_BdSetBufAddr(XAxiDma_Bd* BdPtr, UINTPTR Addr); -u32 XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd* BdPtr, UINTPTR Addr); -int XAxiDma_BdSetAppWord(XAxiDma_Bd * BdPtr, int Offset, u32 Word); -u32 XAxiDma_BdGetAppWord(XAxiDma_Bd * BdPtr, int Offset, int *Valid); -void XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data); - -/* Debug utility - */ -void XAxiDma_DumpBd(XAxiDma_Bd* BdPtr); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxidma_bdring.h b/thirdparty/libxil/include/xilinx/xaxidma_bdring.h deleted file mode 100644 index 351f65827..000000000 --- a/thirdparty/libxil/include/xilinx/xaxidma_bdring.h +++ /dev/null @@ -1,526 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xaxidma_bdring.h -* @addtogroup axidma_v9_0 -* @{ -* -* This file contains DMA channel related structure and constant definition -* as well as function prototypes. Each DMA channel is managed by a Buffer -* Descriptor ring, and XAxiDma_BdRing is chosen as the symbol prefix used in -* this file. See xaxidma.h for more information on how a BD ring is managed. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a jz   05/18/10 First release
-* 2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
-*                     updated tcl file, added xaxidma_porting_guide.h
-* 3.00a jz   11/22/10 Support IP core parameters change
-* 6.00a srt  01/24/12 Added support for Multi-Channel DMA.
-*		      - New API
-*			* XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr,
-*						int RingIndex)
-*		      - Changed APIs
-*			* XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
-*					int RingIndex)
-*			* XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-*			* XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
-*        			int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
-*			* XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-*			* XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
-*						 int RingIndex)
-* 7.00a srt  06/18/12  All the APIs changed in v6_00_a are reverted back for
-*		       backward compatibility.
-*
-*
-* 
-* -******************************************************************************/ - -#ifndef XAXIDMA_BDRING_H_ /* prevent circular inclusions */ -#define XAXIDMA_BDRING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xstatus.h" -#include "xaxidma_bd.h" - - - -/************************** Constant Definitions *****************************/ -/* State of a DMA channel - */ -#define AXIDMA_CHANNEL_NOT_HALTED 1 -#define AXIDMA_CHANNEL_HALTED 2 - -/* Argument constant to simplify argument setting - */ -#define XAXIDMA_NO_CHANGE 0xFFFFFFFF -#define XAXIDMA_ALL_BDS 0x0FFFFFFF /* 268 Million */ - -/**************************** Type Definitions *******************************/ - -/** Container structure for descriptor storage control. If address translation - * is enabled, then all addresses and pointers excluding FirstBdPhysAddr are - * expressed in terms of the virtual address. - */ -typedef struct { - u32 ChanBase; /**< physical base address*/ - - int IsRxChannel; /**< Is this a receive channel */ - volatile int RunState; /**< Whether channel is running */ - int HasStsCntrlStrm; /**< Whether has stscntrl stream */ - int HasDRE; - int DataWidth; - int Addr_ext; - u32 MaxTransferLen; - - UINTPTR FirstBdPhysAddr; /**< Physical address of 1st BD in list */ - UINTPTR FirstBdAddr; /**< Virtual address of 1st BD in list */ - UINTPTR LastBdAddr; /**< Virtual address of last BD in the list */ - u32 Length; /**< Total size of ring in bytes */ - UINTPTR Separation; /**< Number of bytes between the starting - address of adjacent BDs */ - XAxiDma_Bd *FreeHead; /**< First BD in the free group */ - XAxiDma_Bd *PreHead; /**< First BD in the pre-work group */ - XAxiDma_Bd *HwHead; /**< First BD in the work group */ - XAxiDma_Bd *HwTail; /**< Last BD in the work group */ - XAxiDma_Bd *PostHead; /**< First BD in the post-work group */ - XAxiDma_Bd *BdaRestart; /**< BD to load when channel is started */ - int FreeCnt; /**< Number of allocatable BDs in free group */ - int PreCnt; /**< Number of BDs in pre-work group */ - int HwCnt; /**< Number of BDs in work group */ - int PostCnt; /**< Number of BDs in post-work group */ - int AllCnt; /**< Total Number of BDs for channel */ - int RingIndex; /**< Ring Index */ -} XAxiDma_BdRing; - -/***************** Macros (Inline Functions) Definitions *********************/ - -/*****************************************************************************/ -/** -* Use this macro at initialization time to determine how many BDs will fit -* within the given memory constraints. -* -* The results of this macro can be provided to XAxiDma_BdRingCreate(). -* -* @param Alignment specifies what byte alignment the BDs must fall -* on and must be a power of 2 to get an accurate calculation -* (32, 64, 126,...) -* @param Bytes is the number of bytes to be used to store BDs. -* -* @return Number of BDs that can fit in the given memory area -* -* @note -* C-style signature: -* int XAxiDma_BdRingCntCalc(u32 Alignment, u32 Bytes) -* This function is used only when system is configured as SG mode -* -******************************************************************************/ -#define XAxiDma_BdRingCntCalc(Alignment, Bytes) \ - (uint32_t)((Bytes)/((sizeof(XAxiDma_Bd)+((Alignment)-1))&~((Alignment)-1))) - -/*****************************************************************************/ -/** -* Use this macro at initialization time to determine how many bytes of memory -* are required to contain a given number of BDs at a given alignment. -* -* @param Alignment specifies what byte alignment the BDs must fall on. -* This parameter must be a power of 2 to get an accurate -* calculation (32, 64,128,...) -* @param NumBd is the number of BDs to calculate memory size -* requirements -* -* @return The number of bytes of memory required to create a BD list -* with the given memory constraints. -* -* @note -* C-style signature: -* int XAxiDma_BdRingMemCalc(u32 Alignment, u32 NumBd) -* This function is used only when system is configured as SG mode -* -******************************************************************************/ -#define XAxiDma_BdRingMemCalc(Alignment, NumBd) \ - (int)((sizeof(XAxiDma_Bd)+((Alignment)-1)) & ~((Alignment)-1))*(NumBd) - -/****************************************************************************/ -/** -* Return the total number of BDs allocated by this channel with -* XAxiDma_BdRingCreate(). -* -* @param RingPtr is the BD ring to operate on. -* -* @return The total number of BDs allocated for this channel. -* -* @note -* C-style signature: -* int XAxiDma_BdRingGetCnt(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetCnt(RingPtr) ((RingPtr)->AllCnt) - -/****************************************************************************/ -/** -* Return the number of BDs allocatable with XAxiDma_BdRingAlloc() for pre- -* processing. -* -* @param RingPtr is the BD ring to operate on. -* -* @return The number of BDs currently allocatable. -* -* @note -* C-style signature: -* int XAxiDma_BdRingGetFreeCnt(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt) - - -/****************************************************************************/ -/** -* Snap shot the latest BD a BD ring is processing. -* -* @param RingPtr is the BD ring to operate on. -* -* @return None -* -* @note -* C-style signature: -* void XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingSnapShotCurrBd(RingPtr) \ - { \ - if (!RingPtr->IsRxChannel) { \ - (RingPtr)->BdaRestart = (XAxiDma_Bd *) \ - XAxiDma_ReadReg((RingPtr)->ChanBase, \ - XAXIDMA_CDESC_OFFSET); \ - } else { \ - if (!RingPtr->RingIndex) { \ - (RingPtr)->BdaRestart = (XAxiDma_Bd *) \ - XAxiDma_ReadReg( \ - (RingPtr)->ChanBase, \ - XAXIDMA_CDESC_OFFSET); \ - } else { \ - (RingPtr)->BdaRestart = (XAxiDma_Bd *) \ - XAxiDma_ReadReg( \ - (RingPtr)->ChanBase, \ - (XAXIDMA_RX_CDESC0_OFFSET + \ - (RingPtr->RingIndex - 1) * \ - XAXIDMA_RX_NDESC_OFFSET)); \ - } \ - } \ - } - -/****************************************************************************/ -/** -* Get the BD a BD ring is processing. -* -* @param RingPtr is the BD ring to operate on. -* -* @return The current BD that the BD ring is working on -* -* @note -* C-style signature: -* XAxiDma_Bd * XAxiDma_BdRingGetCurrBd(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetCurrBd(RingPtr) \ - (XAxiDma_Bd *)XAxiDma_ReadReg((RingPtr)->ChanBase, \ - XAXIDMA_CDESC_OFFSET) \ - -/****************************************************************************/ -/** -* Return the next BD in the ring. -* -* @param RingPtr is the BD ring to operate on. -* @param BdPtr is the current BD. -* -* @return The next BD in the ring relative to the BdPtr parameter. -* -* @note -* C-style signature: -* XAxiDma_Bd *XAxiDma_BdRingNext(XAxiDma_BdRing* RingPtr, -* XAxiDma_Bd *BdPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingNext(RingPtr, BdPtr) \ - (((UINTPTR)(BdPtr) >= (RingPtr)->LastBdAddr) ? \ - (UINTPTR)(RingPtr)->FirstBdAddr : \ - (UINTPTR)((UINTPTR)(BdPtr) + (RingPtr)->Separation)) - -/****************************************************************************/ -/** -* Return the previous BD in the ring. -* -* @param RingPtr is the DMA channel to operate on. -* @param BdPtr is the current BD. -* -* @return The previous BD in the ring relative to the BdPtr parameter. -* -* @note -* C-style signature: -* XAxiDma_Bd *XAxiDma_BdRingPrev(XAxiDma_BdRing* RingPtr, -* XAxiDma_Bd *BdPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingPrev(RingPtr, BdPtr) \ - (((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ? \ - (XAxiDma_Bd*)(RingPtr)->LastBdAddr : \ - (XAxiDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation)) - -/****************************************************************************/ -/** -* Retrieve the contents of the channel status register -* -* @param RingPtr is the channel instance to operate on. -* -* @return Current contents of status register -* -* @note -* C-style signature: -* u32 XAxiDma_BdRingGetSr(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetSr(RingPtr) \ - XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) - -/****************************************************************************/ -/** -* Get error bits of a DMA channel -* -* @param RingPtr is the channel instance to operate on. -* -* @return Rrror bits in the status register, they should be interpreted -* with XAXIDMA_ERR_*_MASK defined in xaxidma_hw.h -* -* @note -* C-style signature: -* u32 XAxiDma_BdRingGetError(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetError(RingPtr) \ - (XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \ - & XAXIDMA_ERR_ALL_MASK) - -/****************************************************************************/ -/** -* Check whether a DMA channel is started, meaning the channel is not halted. -* -* @param RingPtr is the channel instance to operate on. -* -* @return -* - 1 if channel is started -* - 0 otherwise -* -* @note -* C-style signature: -* int XAxiDma_BdRingHwIsStarted(XAxiDma_BdRing* RingPtr) -* -*****************************************************************************/ -#define XAxiDma_BdRingHwIsStarted(RingPtr) \ - ((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \ - & XAXIDMA_HALTED_MASK) ? FALSE : TRUE) - -/****************************************************************************/ -/** -* Check if the current DMA channel is busy with a DMA operation. -* -* @param RingPtr is the channel instance to operate on. -* -* @return -* - 1 if the DMA is busy. -* - 0 otherwise -* -* @note -* C-style signature: -* int XAxiDma_BdRingBusy(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingBusy(RingPtr) \ - (XAxiDma_BdRingHwIsStarted(RingPtr) && \ - ((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \ - & XAXIDMA_IDLE_MASK) ? FALSE : TRUE)) - -/****************************************************************************/ -/** -* Set interrupt enable bits for a channel. This operation will modify the -* XAXIDMA_CR_OFFSET register. -* -* @param RingPtr is the channel instance to operate on. -* @param Mask consists of the interrupt signals to enable.Bits not -* specified in the mask are not affected. -* -* @note -* C-style signature: -* void XAxiDma_BdRingIntEnable(XAxiDma_BdRing* RingPtr, u32 Mask) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingIntEnable(RingPtr, Mask) \ - (XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \ - XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \ - | ((Mask) & XAXIDMA_IRQ_ALL_MASK))) - -/****************************************************************************/ -/** -* Get enabled interrupts of a channel. It is in XAXIDMA_CR_OFFSET register. -* -* @param RingPtr is the channel instance to operate on. -* @return Enabled interrupts of a channel. Use XAXIDMA_IRQ_* defined in -* xaxidma_hw.h to interpret this returned value. -* -* @note -* C-style signature: -* u32 XAxiDma_BdRingIntGetEnabled(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingIntGetEnabled(RingPtr) \ - (XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \ - & XAXIDMA_IRQ_ALL_MASK) - -/****************************************************************************/ -/** -* Clear interrupt enable bits for a channel. It modifies the -* XAXIDMA_CR_OFFSET register. -* -* @param RingPtr is the channel instance to operate on. -* @param Mask consists of the interrupt signals to disable.Bits not -* specified in the Mask are not affected. -* -* @note -* C-style signature: -* void XAxiDma_BdRingIntDisable(XAxiDma_BdRing* RingPtr, -* u32 Mask) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingIntDisable(RingPtr, Mask) \ - (XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \ - XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) & \ - ~((Mask) & XAXIDMA_IRQ_ALL_MASK))) - -/****************************************************************************/ -/** -* Retrieve the contents of the channel's IRQ register XAXIDMA_SR_OFFSET. This -* operation can be used to see which interrupts are pending. -* -* @param RingPtr is the channel instance to operate on. -* -* @return Current contents of the IRQ_OFFSET register. Use -* XAXIDMA_IRQ_*** values defined in xaxidma_hw.h to interpret -* the returned value. -* -* @note -* C-style signature: -* u32 XAxiDma_BdRingGetIrq(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingGetIrq(RingPtr) \ - (XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \ - & XAXIDMA_IRQ_ALL_MASK) - -/****************************************************************************/ -/** -* Acknowledge asserted interrupts. It modifies XAXIDMA_SR_OFFSET register. -* A mask bit set for an unasserted interrupt has no effect. -* -* @param RingPtr is the channel instance to operate on. -* @param Mask are the interrupt signals to acknowledge -* -* @note -* C-style signature: -* void XAxiDma_BdRingAckIrq(XAxiDma_BdRing* RingPtr) -* This function is used only when system is configured as SG mode -* -*****************************************************************************/ -#define XAxiDma_BdRingAckIrq(RingPtr, Mask) \ - XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET,\ - (Mask) & XAXIDMA_IRQ_ALL_MASK) - -/************************* Function Prototypes ******************************/ - -/* - * Descriptor ring functions xaxidma_bdring.c - */ -int XAxiDma_StartBdRingHw(XAxiDma_BdRing* RingPtr); -int XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing* RingPtr); -u32 XAxiDma_BdRingCreate(XAxiDma_BdRing * RingPtr, UINTPTR PhysAddr, - UINTPTR VirtAddr, u32 Alignment, int BdCount); -int XAxiDma_BdRingClone(XAxiDma_BdRing * RingPtr, XAxiDma_Bd * SrcBdPtr); -int XAxiDma_BdRingAlloc(XAxiDma_BdRing * RingPtr, int NumBd, - XAxiDma_Bd ** BdSetPtr); -int XAxiDma_BdRingUnAlloc(XAxiDma_BdRing * RingPtr, int NumBd, - XAxiDma_Bd * BdSetPtr); -int XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr, int NumBd, - XAxiDma_Bd * BdSetPtr); -int XAxiDma_BdRingFromHw(XAxiDma_BdRing * RingPtr, int BdLimit, - XAxiDma_Bd ** BdSetPtr); -int XAxiDma_BdRingFree(XAxiDma_BdRing * RingPtr, int NumBd, - XAxiDma_Bd * BdSetPtr); -int XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr); -int XAxiDma_BdRingSetCoalesce(XAxiDma_BdRing * RingPtr, u32 Counter, u32 Timer); -void XAxiDma_BdRingGetCoalesce(XAxiDma_BdRing * RingPtr, - u32 *CounterPtr, u32 *TimerPtr); - -/* The following functions are for debug only - */ -int XAxiDma_BdRingCheck(XAxiDma_BdRing * RingPtr); -void XAxiDma_BdRingDumpRegs(XAxiDma_BdRing *RingPtr); -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxidma_hw.h b/thirdparty/libxil/include/xilinx/xaxidma_hw.h deleted file mode 100644 index cc467a83b..000000000 --- a/thirdparty/libxil/include/xilinx/xaxidma_hw.h +++ /dev/null @@ -1,344 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** - * @file xaxidma_hw.h -* @addtogroup axidma_v9_0 -* @{ - * - * Hardware definition file. It defines the register interface and Buffer - * Descriptor (BD) definitions. - * - *
- * MODIFICATION HISTORY:
- *
- * Ver   Who  Date     Changes
- * ----- ---- -------- -------------------------------------------------------
- * 1.00a jz   05/18/10 First release
- * 2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
- *                     updated tcl file, added xaxidma_porting_guide.h
- * 3.00a jz   11/22/10 Support IP core parameters change
- * 4.00a rkv  02/22/11 Added support for simple DMA mode
- * 6.00a srt  01/24/12 Added support for Multi-Channel DMA mode
- * 8.0   srt  01/29/14 Added support for Micro DMA Mode and Cyclic mode of
- *		       operations.
- *
- * 
- * - *****************************************************************************/ - -#ifndef XAXIDMA_HW_H_ /* prevent circular inclusions */ -#define XAXIDMA_HW_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "xil_types.h" -#include "xil_io.h" - -/************************** Constant Definitions *****************************/ - -/** @name DMA Transfer Direction - * @{ - */ -#define XAXIDMA_DMA_TO_DEVICE 0x00 -#define XAXIDMA_DEVICE_TO_DMA 0x01 - - -/** @name Buffer Descriptor Alignment - * @{ - */ -#define XAXIDMA_BD_MINIMUM_ALIGNMENT 0x40 /**< Minimum byte alignment - requirement for descriptors to - satisfy both hardware/software - needs */ -/*@}*/ - -/** @name Micro DMA Buffer Address Alignment - * @{ - */ -#define XAXIDMA_MICROMODE_MIN_BUF_ALIGN 0xFFF /**< Minimum byte alignment - requirement for buffer address - in Micro DMA mode */ -/*@}*/ - -/** @name Maximum transfer length - * This is determined by hardware - * @{ - */ -#define XAXIDMA_MAX_TRANSFER_LEN 0x7FFFFF /* Max length hw supports */ -#define XAXIDMA_MCHAN_MAX_TRANSFER_LEN 0x00FFFF /* Max length MCDMA - hw supports */ -/*@}*/ - -/* Register offset definitions. Register accesses are 32-bit. - */ -/** @name Device registers - * Register sets on TX and RX channels are identical - * @{ - */ -#define XAXIDMA_TX_OFFSET 0x00000000 /**< TX channel registers base - * offset */ -#define XAXIDMA_RX_OFFSET 0x00000030 /**< RX channel registers base - * offset */ - -/* This set of registers are applicable for both channels. Add - * XAXIDMA_TX_OFFSET to get to TX channel, and XAXIDMA_RX_OFFSET to get to RX - * channel - */ -#define XAXIDMA_CR_OFFSET 0x00000000 /**< Channel control */ -#define XAXIDMA_SR_OFFSET 0x00000004 /**< Status */ -#define XAXIDMA_CDESC_OFFSET 0x00000008 /**< Current descriptor pointer */ -#define XAXIDMA_CDESC_MSB_OFFSET 0x0000000C /**< Current descriptor pointer */ -#define XAXIDMA_TDESC_OFFSET 0x00000010 /**< Tail descriptor pointer */ -#define XAXIDMA_TDESC_MSB_OFFSET 0x00000014 /**< Tail descriptor pointer */ -#define XAXIDMA_SRCADDR_OFFSET 0x00000018 /**< Simple mode source address - pointer */ -#define XAXIDMA_SRCADDR_MSB_OFFSET 0x0000001C /**< Simple mode source address - pointer */ -#define XAXIDMA_DESTADDR_OFFSET 0x00000018 /**< Simple mode destination address pointer */ -#define XAXIDMA_DESTADDR_MSB_OFFSET 0x0000001C /**< Simple mode destination address pointer */ -#define XAXIDMA_BUFFLEN_OFFSET 0x00000028 /**< Tail descriptor pointer */ -#define XAXIDMA_SGCTL_OFFSET 0x0000002c /**< SG Control Register */ - -/** Multi-Channel DMA Descriptor Offsets **/ -#define XAXIDMA_RX_CDESC0_OFFSET 0x00000040 /**< Rx Current Descriptor 0 */ -#define XAXIDMA_RX_CDESC0_MSB_OFFSET 0x00000044 /**< Rx Current Descriptor 0 */ -#define XAXIDMA_RX_TDESC0_OFFSET 0x00000048 /**< Rx Tail Descriptor 0 */ -#define XAXIDMA_RX_TDESC0_MSB_OFFSET 0x0000004C /**< Rx Tail Descriptor 0 */ -#define XAXIDMA_RX_NDESC_OFFSET 0x00000020 /**< Rx Next Descriptor Offset */ -/*@}*/ - -/** @name Bitmasks of XAXIDMA_CR_OFFSET register - * @{ - */ -#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /**< Start/stop DMA channel */ -#define XAXIDMA_CR_RESET_MASK 0x00000004 /**< Reset DMA engine */ -#define XAXIDMA_CR_KEYHOLE_MASK 0x00000008 /**< Keyhole feature */ -#define XAXIDMA_CR_CYCLIC_MASK 0x00000010 /**< Cyclic Mode */ -/*@}*/ - -/** @name Bitmasks of XAXIDMA_SR_OFFSET register - * - * This register reports status of a DMA channel, including - * run/stop/idle state, errors, and interrupts (note that interrupt - * masks are shared with XAXIDMA_CR_OFFSET register, and are defined - * in the _IRQ_ section. - * - * The interrupt coalescing threshold value and delay counter value are - * also shared with XAXIDMA_CR_OFFSET register, and are defined in a - * later section. - * @{ - */ -#define XAXIDMA_HALTED_MASK 0x00000001 /**< DMA channel halted */ -#define XAXIDMA_IDLE_MASK 0x00000002 /**< DMA channel idle */ -#define XAXIDMA_ERR_INTERNAL_MASK 0x00000010 /**< Datamover internal - * err */ -#define XAXIDMA_ERR_SLAVE_MASK 0x00000020 /**< Datamover slave err */ -#define XAXIDMA_ERR_DECODE_MASK 0x00000040 /**< Datamover decode - * err */ -#define XAXIDMA_ERR_SG_INT_MASK 0x00000100 /**< SG internal err */ -#define XAXIDMA_ERR_SG_SLV_MASK 0x00000200 /**< SG slave err */ -#define XAXIDMA_ERR_SG_DEC_MASK 0x00000400 /**< SG decode err */ -#define XAXIDMA_ERR_ALL_MASK 0x00000770 /**< All errors */ - -/** @name Bitmask for interrupts - * These masks are shared by XAXIDMA_CR_OFFSET register and - * XAXIDMA_SR_OFFSET register - * @{ - */ -#define XAXIDMA_IRQ_IOC_MASK 0x00001000 /**< Completion intr */ -#define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /**< Delay interrupt */ -#define XAXIDMA_IRQ_ERROR_MASK 0x00004000 /**< Error interrupt */ -#define XAXIDMA_IRQ_ALL_MASK 0x00007000 /**< All interrupts */ -/*@}*/ - -/** @name Bitmask and shift for delay and coalesce - * These masks are shared by XAXIDMA_CR_OFFSET register and - * XAXIDMA_SR_OFFSET register - * @{ - */ -#define XAXIDMA_DELAY_MASK 0xFF000000 /**< Delay timeout - * counter */ -#define XAXIDMA_COALESCE_MASK 0x00FF0000 /**< Coalesce counter */ - -#define XAXIDMA_DELAY_SHIFT 24 -#define XAXIDMA_COALESCE_SHIFT 16 -/*@}*/ - - -/* Buffer Descriptor (BD) definitions - */ - -/** @name Buffer Descriptor offsets - * USR* fields are defined by higher level IP. - * setup for EMAC type devices. The first 13 words are used by hardware. - * All words after the 13rd word are for software use only. - * @{ - */ -#define XAXIDMA_BD_NDESC_OFFSET 0x00 /**< Next descriptor pointer */ -#define XAXIDMA_BD_NDESC_MSB_OFFSET 0x04 /**< Next descriptor pointer */ -#define XAXIDMA_BD_BUFA_OFFSET 0x08 /**< Buffer address */ -#define XAXIDMA_BD_BUFA_MSB_OFFSET 0x0C /**< Buffer address */ -#define XAXIDMA_BD_MCCTL_OFFSET 0x10 /**< Multichannel Control Fields */ -#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET 0x14 /**< 2D Transfer Sizes */ -#define XAXIDMA_BD_CTRL_LEN_OFFSET 0x18 /**< Control/buffer length */ -#define XAXIDMA_BD_STS_OFFSET 0x1C /**< Status */ - -#define XAXIDMA_BD_USR0_OFFSET 0x20 /**< User IP specific word0 */ -#define XAXIDMA_BD_USR1_OFFSET 0x24 /**< User IP specific word1 */ -#define XAXIDMA_BD_USR2_OFFSET 0x28 /**< User IP specific word2 */ -#define XAXIDMA_BD_USR3_OFFSET 0x2C /**< User IP specific word3 */ -#define XAXIDMA_BD_USR4_OFFSET 0x30 /**< User IP specific word4 */ - -#define XAXIDMA_BD_ID_OFFSET 0x34 /**< Sw ID */ -#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET 0x38 /**< Whether has stscntrl strm */ -#define XAXIDMA_BD_HAS_DRE_OFFSET 0x3C /**< Whether has DRE */ -#define XAXIDMA_BD_ADDRLEN_OFFSET 0x40 /**< Check for BD Addr */ - -#define XAXIDMA_BD_HAS_DRE_MASK 0xF00 /**< Whether has DRE mask */ -#define XAXIDMA_BD_WORDLEN_MASK 0xFF /**< Whether has DRE mask */ - -#define XAXIDMA_BD_HAS_DRE_SHIFT 8 /**< Whether has DRE shift */ -#define XAXIDMA_BD_WORDLEN_SHIFT 0 /**< Whether has DRE shift */ - -#define XAXIDMA_BD_START_CLEAR 8 /**< Offset to start clear */ -#define XAXIDMA_BD_BYTES_TO_CLEAR 48 /**< BD specific bytes to be - * cleared */ - -#define XAXIDMA_BD_NUM_WORDS 20U /**< Total number of words for - * one BD*/ -#define XAXIDMA_BD_HW_NUM_BYTES 52 /**< Number of bytes hw used */ - -/* The offset of the last app word. - */ -#define XAXIDMA_LAST_APPWORD 4 - -/*@}*/ -#define XAXIDMA_DESC_LSB_MASK (0xFFFFFFC0U) /**< LSB Address mask */ - -/** @name Bitmasks of XAXIDMA_BD_CTRL_OFFSET register - * @{ - */ -#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /**< First tx packet */ -#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /**< Last tx packet */ -#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /**< All control bits */ -/*@}*/ - -/** @name Bitmasks of XAXIDMA_BD_STS_OFFSET register - * @{ - */ -#define XAXIDMA_BD_STS_COMPLETE_MASK 0x80000000 /**< Completed */ -#define XAXIDMA_BD_STS_DEC_ERR_MASK 0x40000000 /**< Decode error */ -#define XAXIDMA_BD_STS_SLV_ERR_MASK 0x20000000 /**< Slave error */ -#define XAXIDMA_BD_STS_INT_ERR_MASK 0x10000000 /**< Internal err */ -#define XAXIDMA_BD_STS_ALL_ERR_MASK 0x70000000 /**< All errors */ -#define XAXIDMA_BD_STS_RXSOF_MASK 0x08000000 /**< First rx pkt */ -#define XAXIDMA_BD_STS_RXEOF_MASK 0x04000000 /**< Last rx pkt */ -#define XAXIDMA_BD_STS_ALL_MASK 0xFC000000 /**< All status bits */ -/*@}*/ - -/** @name Bitmasks and shift values for XAXIDMA_BD_MCCTL_OFFSET register - * @{ - */ -#define XAXIDMA_BD_TDEST_FIELD_MASK 0x0000000F -#define XAXIDMA_BD_TID_FIELD_MASK 0x00000F00 -#define XAXIDMA_BD_TUSER_FIELD_MASK 0x000F0000 -#define XAXIDMA_BD_ARCACHE_FIELD_MASK 0x0F000000 -#define XAXIDMA_BD_ARUSER_FIELD_MASK 0xF0000000 - -#define XAXIDMA_BD_TDEST_FIELD_SHIFT 0 -#define XAXIDMA_BD_TID_FIELD_SHIFT 8 -#define XAXIDMA_BD_TUSER_FIELD_SHIFT 16 -#define XAXIDMA_BD_ARCACHE_FIELD_SHIFT 24 -#define XAXIDMA_BD_ARUSER_FIELD_SHIFT 28 - -/** @name Bitmasks and shift values for XAXIDMA_BD_STRIDE_VSIZE_OFFSET register - * @{ - */ -#define XAXIDMA_BD_STRIDE_FIELD_MASK 0x0000FFFF -#define XAXIDMA_BD_VSIZE_FIELD_MASK 0xFFF80000 - -#define XAXIDMA_BD_STRIDE_FIELD_SHIFT 0 -#define XAXIDMA_BD_VSIZE_FIELD_SHIFT 19 - -/**************************** Type Definitions *******************************/ - -/***************** Macros (Inline Functions) Definitions *********************/ - -#define XAxiDma_In32 Xil_In32 -#define XAxiDma_Out32 Xil_Out32 - -/*****************************************************************************/ -/** -* -* Read the given register. -* -* @param BaseAddress is the base address of the device -* @param RegOffset is the register offset to be read -* -* @return The 32-bit value of the register -* -* @note -* C-style signature: -* u32 XAxiDma_ReadReg(u32 BaseAddress, u32 RegOffset) -* -******************************************************************************/ -#define XAxiDma_ReadReg(BaseAddress, RegOffset) \ - XAxiDma_In32((BaseAddress) + (RegOffset)) - -/*****************************************************************************/ -/** -* -* Write the given register. -* -* @param BaseAddress is the base address of the device -* @param RegOffset is the register offset to be written -* @param Data is the 32-bit value to write to the register -* -* @return None. -* -* @note -* C-style signature: -* void XAxiDma_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data) -* -******************************************************************************/ -#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data) \ - XAxiDma_Out32((BaseAddress) + (RegOffset), (Data)) - -#ifdef __cplusplus -} -#endif - -#endif -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxidma_porting_guide.h b/thirdparty/libxil/include/xilinx/xaxidma_porting_guide.h deleted file mode 100644 index ff10ddc7c..000000000 --- a/thirdparty/libxil/include/xilinx/xaxidma_porting_guide.h +++ /dev/null @@ -1,254 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xaxidma_porting_guide.h -* @addtogroup axidma_v9_0 -* @{ -* -* This is a guide on how to move from using the xlldma driver to use xaxidma -* driver. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a jz   05/18/10 First release
-* 2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
-*                     updated tcl file, added xaxidma_porting_guide.h
-* 4.00a rkv  02/22/11 Added support for simple DMA mode
-* 6.00a srt  03/27/12 Added support for MCDMA mode
-* 7.00a srt  06/18/12 API calls are reverted back for backward compatibility.
-*
-* 
-* -* Overview -* -* The API for xaxidma driver is similar to xlldma driver. The prefix for the -* API functions and structures is XAxiDma_ for the xaxidma driver. -* -* Due to hardware feature changes, signatures of some API functions are a -* little bit different from the xlldma API functions. -* -* We present API functions: -* - That only have prefix changes -* - That have different return type -* - That are new API functions -* - That have been removed -* -* Note that data structures have different prefix of XAxiDma_. Those API -* functions, that have data structures with prefix change, are considered as -* prefix change. -* -* API Functions That Only Have Prefix Changes -* -*
-*         xlldma driver              |         xaxidma driver (upto v5_00_a)
-* -----------------------------------------------------------------------
-*    XLlDma_Reset(...)               |  XAxiDma_Reset(...)
-*    XLlDma_BdRingSnapShotCurrBd(...)|  XAxiDma_BdRingSnapShotCurrBd(...)
-*    XLlDma_BdRingNext(...)          |  XAxiDma_BdRingNext(...)
-*    XLlDma_BdRingPrev(...)          |  XAxiDma_BdRingPrev(...)
-*    XLlDma_BdRingGetSr(...)         |  XAxiDma_BdRingGetSr(...)
-*    XLlDma_BdRingBusy(...)          |  XAxiDma_BdRingBusy(...)
-*    XLlDma_BdRingIntEnable(...)     |  XAxiDma_BdRingIntEnable(...)
-*    XLlDma_BdRingIntDisable(...)    |  XAxiDma_BdRingIntDisable(...)
-*    XLlDma_BdRingIntGetEnabled(...) |  XAxiDma_BdRingIntGetEnabled(...)
-*    XLlDma_BdRingGetIrq(...)        |  XAxiDma_BdRingGetIrq(...)
-*    XLlDma_BdRingAckIrq(...)        |  XAxiDma_BdRingAckIrq(...)
-*    XLlDma_BdRingCreate(...)        |  XAxiDma_BdRingCreate(...)
-*    XLlDma_BdRingClone(...)         |  XAxiDma_BdRingClone(...)
-*    XLlDma_BdRingAlloc(...)         |  XAxiDma_BdRingAlloc(...)
-*    XLlDma_BdRingUnAlloc(...)       |  XAxiDma_BdRingUnAlloc(...)
-*    XLlDma_BdRingToHw(...)          |  XAxiDma_BdRingToHw(...)
-*    XLlDma_BdRingFromHw(...)        |  XAxiDma_BdRingFromHw(...)
-*    XLlDma_BdRingFree(...)          |  XAxiDma_BdRingFree(...)
-*    XLlDma_BdRingStart(...)         |  XAxiDma_BdRingStart(...)
-*    XLlDma_BdRingCheck(...)         |  XAxiDma_BdRingCheck(...)
-*    XLlDma_BdRingSetCoalesce(...)   |  XAxiDma_BdRingSetCoalesce(...)
-*    XLlDma_BdRingGetCoalesce(...)   |  XAxiDma_BdRingGetCoalesce(...)
-*    XLlDma_BdRead(...)              |  XAxiDma_BdRead(...)
-*    XLlDma_BdWrite(...)             |  XAxiDma_BdWrite(...)
-*    XLlDma_BdClear(...)             |  XAxiDma_BdClear(...)
-*    XLlDma_BdSetId(...)             |  XAxiDma_BdSetId(...)
-*    XLlDma_BdGetId(...)             |  XAxiDma_BdGetId(...)
-*    XLlDma_BdGetLength(...)         |  XAxiDma_BdGetLength(...)
-*    XLlDma_BdGetBufAddr(...)        |  XAxiDma_BdGetBufAddr(...)
-*
-*
-* -* API Functions That Have Different Return Type -* -* Due to possible hardware failures, The caller should check the return value -* of the following functions. -* -*
-*         xlldma driver              |         xaxidma driver
-* -----------------------------------------------------------------------
-* void XLlDma_Pause(...)             | int XAxiDma_Pause(...)
-* void XLlDma_Resume(...)            | int XAxiDma_Resume(...)
-* 
-* -* The following functions have return type changed: -* -*
-*         xlldma driver              |         xaxidma driver
-* -----------------------------------------------------------------------
-* XLlDma_BdRing XLlDma_GetRxRing(...)| XAxiDma_BdRing * XAxiDma_GetRxRing(...)
-* XLlDma_BdRing XLlDma_GetTxRing(...)| XAxiDma_BdRing * XAxiDma_GetTxRing(...)
-* u32 XLlDma_BdRingMemCalc(...)      | int XAxiDma_BdRingMemCalc(...)
-* u32 XLlDma_BdRingCntCalc(...)      | int XAxiDma_BdRingCntCalc(...)
-* u32 XLlDma_BdRingGetCnt(...)       | int XAxiDma_BdRingGetCnt(...)
-* u32 XLlDma_BdRingGetFreeCnt(...)   | int XAxiDma_BdRingGetFreeCnt(...)
-* void XLlDma_BdSetLength(...)       | int XAxiDma_BdSetLength(...)
-* void XLlDma_BdSetBufAddr(...)      | int XAxiDma_BdSetBufAddr(...)
-*
-* -* API Functions That Are New API Functions -* -* Now that the AXI DMA core is a standalone core, some new API are intrduced. -* Some other functions are added due to hardware interface change, so to -* replace old API functions. -* -* - XAxiDma_Config *XAxiDma_LookupConfig(u32 DeviceId); -* - int XAxiDma_CfgInitialize(XAxiDma * InstancePtr, XAxiDma_Config *Config); -* - int XAxiDma_ResetIsDone(XAxiDma * InstancePtr); -* - XAxiDma_Bd * XAxiDma_BdRingGetCurrBd(XAxiDma_BdRing* RingPtr); -* - int XAxiDma_BdRingHwIsStarted(XAxiDma_BdRing* RingPtr); -* - void XAxiDma_BdRingDumpRegs(XAxiDma_BdRing *RingPtr); -* - int XAxiDma_StartBdRingHw(XAxiDma_BdRing* RingPtr); -* - void XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data); -* - u32 XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr); -* - u32 XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr); -* - int XAxiDma_BdHwCompleted(XAxiDma_Bd* BdPtr); -* - int XAxiDma_BdGetActualLength(XAxiDma_Bd* BdPtr); -* - int XAxiDma_BdSetAppWord(XAxiDma_Bd * BdPtr, int Offset, u32 Word); -* - u32 XAxiDma_BdGetAppWord(XAxiDma_Bd * BdPtr, int Offset, int *Valid); -* -* API Functions That Have Been Removed -* -* Please see individual function comments for how to replace the removed API -* function with new API functions. -* -* - void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress). -* This function is replaced by XAxiDma_LookupConfig()/XAxiDma_CfgInitialize() -* -* - u32 XLlDma_BdRingGetCr(XLlDma_BdRing* RingPtr). -* This is replaced by XAxiDma_BdRingGetError(XAxiDma_BdRing* RingPtr) -* -* - u32 XLlDma_BdRingSetCr(XLlDma_BdRing* RingPtr, u32 Data). -* This function is covered by other API functions: -* - void XAxiDma_BdRingIntEnable(XAxiDma_BdRing* RingPtr, u32 Mask) -* - void XAxiDma_BdRingIntDisable(XAxiDma_BdRing* RingPtr, u32 Mask) -* - int XAxiDma_BdRingSetCoalesce(XAxiDma_BdRing * RingPtr, u32 Counter, -* u32 Timer) -* -* - u32 XLlDma_BdSetStsCtrl(XLlDma_Bd* BdPtr, u32 Data). -* Replaced by XAxiDma_BdSetCtrl(XAxiDma_Bd *BdPtr, u32 Data); -* -* - u32 XLlDma_BdGetStsCtrl(XLlDma_Bd* BdPtr). -* Replaced by XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr) and -* XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr). -* -* API Functions That Have Been Added to support simple DMA mode -* -* - u32 XAxiDma_Busy(XAxiDma *InstancePtr,int Direction); -* - int XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, u32 BuffAddr, int Length, -* int Direction); -* - XAxiDma_HasSg(InstancePtr); -* - XAxiDma_IntrEnable(InstancePtr,Mask,Direction); -* - XAxiDma_IntrGetEnabled(InstancePtr, Direction); -* - XAxiDma_IntrDisable(InstancePtr, Mask, Direction); -* - XAxiDma_IntrGetIrq(InstancePtr, Direction); -* - XAxiDma_IntrAckIrq(InstancePtr, Mask, Direction); -* -* For xaxidma driver v6_00_a Multiple Channel Support -* --------------------------------------------------- -* This driver supports Multi-channel mode and accordingly some APIs are -* changed to index multiple channels. Few new APIs are added. -* - Changed APIs -* * XAxiDma_GetRxRing(InstancePtr, RingIndex) -* * XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex) -* * XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex) -* * XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex) -* * XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex) -* * XAxiDma_SimpleTransfer(XAxiDma *InstancePtr, -* u32 BuffAddr, u32 Length, -* int Direction, int RingIndex) -* * XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr, -* int RingIndex) -* * XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr, -* int RingIndex) -* * XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr, -* int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex) -* * XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr, -* int RingIndex) -* * XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr, -* int RingIndex) -* * XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr, -* u32 LenBytes, u32 LengthMask) -* * XAxiDma_BdGetActualLength(BdPtr, LengthMask) -* * XAxiDma_BdGetLength(BdPtr, LengthMask) -* -* - New APIs -* * XAxiDma_SelectKeyHole(XAxiDma *InstancePtr, -* int Direction, int Select) -* * XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr, -* int RingIndex) -* * XAxiDma_BdSetTId() -* * XAxiDma_BdGetTId() -* * XAxiDma_BdSetTDest() -* * XAxiDma_BdGetTDest() -* * XAxiDma_BdSetTUser() -* * XAxiDma_BdGetTUser() -* * XAxiDma_BdSetARCache() -* * XAxiDma_BdGetARCache() -* * XAxiDma_BdSetARUser() -* * XAxiDma_BdGetARUser() -* * XAxiDma_BdSetStride() -* * XAxiDma_BdGetStride() -* * XAxiDma_BdSetVSize() -* * XAxiDma_BdGetVSize() -* For xaxidma driver v7_00_a -* --------------------------------------------------- -* - New API -* * XAxiDma_GetRxIndexRing(InstancePtr, RingIndex) -* -* - Changed APIs -* All the APIs changed in v6_00_a are reverted back for backward -* compatibility. -* -* -******************************************************************************/ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxis_switch.h b/thirdparty/libxil/include/xilinx/xaxis_switch.h deleted file mode 100644 index 604760916..000000000 --- a/thirdparty/libxil/include/xilinx/xaxis_switch.h +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xaxis_switch.h -* @addtogroup axis_switch_v1_0 -* @{ -* @details -* -* This is the main header file for Xilinx AXI4-Stream Switch Control Router -* core. It is used for routing streams where masters in the system do not know -* final destination address. -* -* Core Features -* -* For a full description of AXI4-Stream Switch Control Router, please see the -* hardware specification. -* -* Software Initialization & Configuration -* -* The application needs to do following steps in order for preparing the -* AXI4-Stream Switch Control Router core to be ready. -* -* - Call XAxisScr_LookupConfig using a device ID to find the core -* configuration. -* - Call XAxisScr_CfgInitialize to initialize the device and the driver -* instance associated with it. -* -* Interrupts -* -* This driver does not have interrupt mechanism. -* -* Virtual Memory -* -* This driver supports Virtual Memory. The RTOS is responsible for calculating -* the correct device base address in Virtual Memory space. -* -* Threads -* -* This driver is not thread safe. Any needs for threads or thread mutual -* exclusion must be satisfied by the layer above this driver. -* -* Asserts -* -* Asserts are used within all Xilinx drivers to enforce constraints on argument -* values. Asserts can be turned off on a system-wide basis by defining at -* compile time, the NDEBUG identifier. By default, asserts are turned on and it -* is recommended that users leave asserts on during development. -* -* Building the driver -* -* The XAXI4-Stream Switch driver is composed of several source files. This -* allows the user to build and link only those parts of the driver that are -* necessary. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who Date     Changes
-* ----- --- -------- --------------------------------------------------
-* 1.00  sha 01/28/15 Initial release.
-* 
-* -******************************************************************************/ -#ifndef XAXIS_SWITCH_H_ -#define XAXIS_SWITCH_H_ /**< Prevent circular inclusions - * by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xaxis_switch_hw.h" -#include "xil_assert.h" -#include "xstatus.h" - -/************************** Constant Definitions *****************************/ - - -/**************************** Type Definitions *******************************/ - -/** -* This typedef contains configuration information for the AXI4-Stream Switch -* core. Each AXI4-Stream Switch device should have a configuration structure -* associated. -*/ -typedef struct { - u16 DeviceId; /**< DeviceId is the unique ID of the AXI4- - * Stream Switch core */ - u32 BaseAddress; /**< BaseAddress is the physical base address - * of the core's registers */ - u8 MaxNumSI; /**< Maximum number of Slave interfaces */ - u8 MaxNumMI; /**< Maximum number of Master interfaces */ -} XAxis_Switch_Config; - -/** -* The AXI4-Stream Switch driver instance data. An instance must be allocated -* for each core in use. -*/ -typedef struct { - XAxis_Switch_Config Config; /**< Hardware Configuration */ - u32 IsReady; /**< Core and the driver instance are - * initialized */ -} XAxis_Switch; - -/***************** Macros (Inline Functions) Definitions *********************/ - -/*****************************************************************************/ -/** -* -* This macro enables register updates. -* -* @param InstancePtr is a pointer to the XAxis_Switch core instance. -* -* @return None. -* -* @note C-style signature: -* void XAxisScr_RegUpdateEnable(XAxis_Switch *InstancePtr) -* -******************************************************************************/ -#define XAxisScr_RegUpdateEnable(InstancePtr) \ - XAxisScr_WriteReg((InstancePtr)->Config.BaseAddress, \ - XAXIS_SCR_CTRL_OFFSET, \ - XAxisScr_ReadReg((InstancePtr)->Config.BaseAddress, \ - XAXIS_SCR_CTRL_OFFSET) | \ - XAXIS_SCR_CTRL_REG_UPDATE_MASK) - -/*****************************************************************************/ -/** -* -* This macro disables register updates. -* -* @param InstancePtr is a pointer to the XAxis_Switch core instance. -* -* @return None. -* -* @note C-style signature: -* void XAxisScr_RegUpdateDisable(XAxis_Switch *InstancePtr) -* -******************************************************************************/ -#define XAxisScr_RegUpdateDisable(InstancePtr) \ - XAxisScr_WriteReg((InstancePtr)->Config.BaseAddress, \ - XAXIS_SCR_CTRL_OFFSET, \ - XAxisScr_ReadReg((InstancePtr)->Config.BaseAddress, \ - XAXIS_SCR_CTRL_OFFSET) & \ - (~XAXIS_SCR_CTRL_REG_UPDATE_MASK)) - -/************************** Function Prototypes ******************************/ - -/* Initialization function in xaxis_switch_sinit.c */ -XAxis_Switch_Config *XAxisScr_LookupConfig(u16 DeviceId); - -/* Initialization and control functions in xaxis_switch.c */ -s32 XAxisScr_CfgInitialize(XAxis_Switch *InstancePtr, - XAxis_Switch_Config *CfgPtr, u32 EffectiveAddr); - -void XAxisScr_MiPortEnable(XAxis_Switch *InstancePtr, u8 MiIndex, - u8 SiIndex); -void XAxisScr_MiPortDisable(XAxis_Switch *InstancePtr, u8 MiIndex); -s32 XAxisScr_IsMiPortEnabled(XAxis_Switch *InstancePtr, u8 MiIndex, - u8 SiIndex); -s32 XAxisScr_IsMiPortDisabled(XAxis_Switch *InstancePtr, u8 MiIndex); -void XAxisScr_MiPortDisableAll(XAxis_Switch *InstancePtr); - -/* Self test function in xaxis_switch_selftest.c */ -s32 XAxisScr_SelfTest(XAxis_Switch *InstancePtr); - -/************************** Variable Declarations ****************************/ - - -#ifdef __cplusplus -} -#endif - -#endif /* End of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xaxis_switch_hw.h b/thirdparty/libxil/include/xilinx/xaxis_switch_hw.h deleted file mode 100644 index f98227e19..000000000 --- a/thirdparty/libxil/include/xilinx/xaxis_switch_hw.h +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xaxis_switch_hw.h -* @addtogroup axis_switch_v1_0 -* @{ -* -* This header file contains identifiers and register-level core functions (or -* macros) that can be used to access the Xilinx AXI4-Stream Switch Control -* Router core. -* -* For more information about the operation of this core see the hardware -* specification and documentation in the higher level driver -* xaxis_switch.h file. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who Date     Changes
-* ----- --- -------- --------------------------------------------------
-* 1.00  sha 01/28/15 Initial release.
-* 
-* -******************************************************************************/ -#ifndef XAXIS_SWITCH_HW_H_ -#define XAXIS_SWITCH_HW_H_ /**< Prevent circular inclusions - * by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_io.h" - -/************************** Constant Definitions *****************************/ - -/** @name MI MUX register offsets -* -* @{ -*/ -#define XAXIS_SCR_CTRL_OFFSET 0x000 /**< Control Register offset */ -#define XAXIS_SCR_MI_MUX_START_OFFSET 0x040 /**< Start of MI MUX Register - * offset */ -#define XAXIS_SCR_MI_MUX_END_OFFSET 0x07C /**< End of MI MUX Register - * offset */ - -/*@}*/ - -/** @name MI MUX Control register mask -* @{ -*/ -#define XAXIS_SCR_CTRL_REG_UPDATE_MASK 0x02 /**< Register Update - * mask */ -/*@}*/ - -/** @name MI MUX register mask -* -* It is applicable for MI[0...15] registers. -* @{ -*/ -#define XAXIS_SCR_MI_X_MUX_MASK 0x0F /**< MI MUX mask */ -#define XAXIS_SCR_MI_X_DISABLE_MASK 0x80000000 /**< MI Disable mask */ -#define XAXIS_SCR_MI_X_DISABLE_SHIFT 31 /**< MI Disable shift */ -/*@}*/ - -/**************************** Type Definitions *******************************/ - - -/***************** Macros (Inline Functions) Definitions *********************/ - -/** @name Register access macro definition -* @{ -*/ -#define XAxisScr_In32 Xil_In32 /**< Input Operations */ -#define XAxisScr_Out32 Xil_Out32 /**< Output Operations */ - -/*****************************************************************************/ -/** -* -* This macro reads a value from a AXI4-Stream Switch register. A 32 bit read -* is performed. If the component is implemented in a smaller width, only the -* least significant data is read from the register. The most significant data -* will be read as 0. -* -* @param BaseAddress is the base address of the XAxis_Switch core -* instance. -* @param RegOffset is the register offset of the register (defined at -* the top of this file). -* -* @return The 32-bit value of the register. -* -* @note C-style signature: -* u32 XAxisScr_ReadReg(u32 BaseAddress, u32 RegOffset) -* -******************************************************************************/ -#define XAxisScr_ReadReg(BaseAddress, RegOffset) \ - XAxisScr_In32((BaseAddress) + ((u32)RegOffset)) - -/*****************************************************************************/ -/** -* -* This macro writes a value to a AXI4-Stream Switch register. A 32 bit write -* is performed. If the component is implemented in a smaller width, only the -* least significant data is written. -* -* @param BaseAddress is the base address of the XAxis_Switch core -* instance. -* @param RegOffset is the register offset of the register (defined at -* the top of this file) to be written. -* @param Data is the 32-bit value to write into the register. -* -* @return None. -* -* @note C-style signature: -* void XAxisScr_WriteReg(u32 BaseAddress, u32 RegOffset, -* u32 Data) -* -******************************************************************************/ -#define XAxisScr_WriteReg(BaseAddress, RegOffset, Data) \ - XAxisScr_Out32((BaseAddress) + ((u32)RegOffset), (u32)(Data)) -/*@}*/ - -/************************** Function Prototypes ******************************/ - - -/************************** Variable Declarations ****************************/ - - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ \ No newline at end of file diff --git a/thirdparty/libxil/include/xilinx/xbasic_types.h b/thirdparty/libxil/include/xilinx/xbasic_types.h deleted file mode 100644 index 7213c7bcc..000000000 --- a/thirdparty/libxil/include/xilinx/xbasic_types.h +++ /dev/null @@ -1,315 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xbasic_types.h -* @addtogroup common_v1_00_a -* @{ -* -* This file contains basic types for Xilinx software IP. These types do not -* follow the standard naming convention with respect to using the component -* name in front of each name because they are considered to be primitives. -* -* @note -* -* This file contains items which are architecture dependent. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who    Date   Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a rmm  12/14/01 First release
-*       rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
-*                     compiler warnings
-* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
-* 1.00a rpm  07/21/04 Added XExceptionHandler typedef for processor exceptions
-* 1.00a xd   11/03/04 Improved support for doxygen.
-* 1.00a wre  01/25/07 Added Linux style data types u32, u16, u8, TRUE, FALSE
-* 1.00a rpm  04/02/07 Added ifndef KERNEL around u32, u16, u8 data types
-* 
-* -******************************************************************************/ - -#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ -#define XBASIC_TYPES_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/***************************** Include Files *********************************/ - - -/************************** Constant Definitions *****************************/ - -#ifndef TRUE -# define TRUE 1 -#endif - -#ifndef FALSE -# define FALSE 0 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -/** Xilinx NULL, TRUE and FALSE legacy support. Deprecated. */ -#define XNULL NULL -#define XTRUE TRUE -#define XFALSE FALSE - - -#define XCOMPONENT_IS_READY 0x11111111 /**< component has been initialized */ -#define XCOMPONENT_IS_STARTED 0x22222222 /**< component has been started */ - -/* the following constants and declarations are for unit test purposes and are - * designed to be used in test applications. - */ -#define XTEST_PASSED 0 -#define XTEST_FAILED 1 - -#define XASSERT_NONE 0 -#define XASSERT_OCCURRED 1 - -extern unsigned int XAssertStatus; -extern void XAssert(char *, int); - -/**************************** Type Definitions *******************************/ - -#include - -/** @name Legacy types - * Deprecated legacy types. - * @{ - */ -typedef uint8_t Xuint8; /**< unsigned 8-bit */ -typedef int8_t Xint8; /**< signed 8-bit */ -typedef uint16_t Xuint16; /**< unsigned 16-bit */ -typedef int16_t Xint16; /**< signed 16-bit */ -typedef uint32_t Xuint32; /**< unsigned 32-bit */ -typedef int32_t Xint32; /**< signed 32-bit */ -typedef float Xfloat32; /**< 32-bit floating point */ -typedef double Xfloat64; /**< 64-bit double precision FP */ -typedef unsigned Xboolean; /**< boolean (XTRUE or XFALSE) */ - -#if !defined __XUINT64__ -typedef struct -{ - Xuint32 Upper; - Xuint32 Lower; -} Xuint64; -#endif - -/** @name New types - * New simple types. - * @{ - */ -#ifndef __KERNEL__ -#ifndef XIL_TYPES_H -typedef Xuint32 u32; -typedef Xuint16 u16; -typedef Xuint8 u8; -#endif -#else -#include -#endif - -/*@}*/ - -/** - * This data type defines an interrupt handler for a device. - * The argument points to the instance of the component - */ -typedef void (*XInterruptHandler) (void *InstancePtr); - -/** - * This data type defines an exception handler for a processor. - * The argument points to the instance of the component - */ -typedef void (*XExceptionHandler) (void *InstancePtr); - -/** - * This data type defines a callback to be invoked when an - * assert occurs. The callback is invoked only when asserts are enabled - */ -typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber); - -/***************** Macros (Inline Functions) Definitions *********************/ - -/*****************************************************************************/ -/** -* Return the most significant half of the 64 bit data type. -* -* @param x is the 64 bit word. -* -* @return The upper 32 bits of the 64 bit word. -* -* @note None. -* -******************************************************************************/ -#define XUINT64_MSW(x) ((x).Upper) - -/*****************************************************************************/ -/** -* Return the least significant half of the 64 bit data type. -* -* @param x is the 64 bit word. -* -* @return The lower 32 bits of the 64 bit word. -* -* @note None. -* -******************************************************************************/ -#define XUINT64_LSW(x) ((x).Lower) - - -#ifndef NDEBUG - -/*****************************************************************************/ -/** -* This assert macro is to be used for functions that do not return anything -* (void). This in conjunction with the XWaitInAssert boolean can be used to -* accomodate tests so that asserts which fail allow execution to continue. -* -* @param expression is the expression to evaluate. If it evaluates to -* false, the assert occurs. -* -* @return Returns void unless the XWaitInAssert variable is true, in which -* case no return is made and an infinite loop is entered. -* -* @note None. -* -******************************************************************************/ -#define XASSERT_VOID(expression) \ -{ \ - if (expression) \ - { \ - XAssertStatus = XASSERT_NONE; \ - } \ - else \ - { \ - XAssert(__FILE__, __LINE__); \ - XAssertStatus = XASSERT_OCCURRED; \ - return; \ - } \ -} - -/*****************************************************************************/ -/** -* This assert macro is to be used for functions that do return a value. This in -* conjunction with the XWaitInAssert boolean can be used to accomodate tests so -* that asserts which fail allow execution to continue. -* -* @param expression is the expression to evaluate. If it evaluates to false, -* the assert occurs. -* -* @return Returns 0 unless the XWaitInAssert variable is true, in which case -* no return is made and an infinite loop is entered. -* -* @note None. -* -******************************************************************************/ -#define XASSERT_NONVOID(expression) \ -{ \ - if (expression) \ - { \ - XAssertStatus = XASSERT_NONE; \ - } \ - else \ - { \ - XAssert(__FILE__, __LINE__); \ - XAssertStatus = XASSERT_OCCURRED; \ - return 0; \ - } \ -} - -/*****************************************************************************/ -/** -* Always assert. This assert macro is to be used for functions that do not -* return anything (void). Use for instances where an assert should always -* occur. -* -* @return Returns void unless the XWaitInAssert variable is true, in which case -* no return is made and an infinite loop is entered. -* -* @note None. -* -******************************************************************************/ -#define XASSERT_VOID_ALWAYS() \ -{ \ - XAssert(__FILE__, __LINE__); \ - XAssertStatus = XASSERT_OCCURRED; \ - return; \ -} - -/*****************************************************************************/ -/** -* Always assert. This assert macro is to be used for functions that do return -* a value. Use for instances where an assert should always occur. -* -* @return Returns void unless the XWaitInAssert variable is true, in which case -* no return is made and an infinite loop is entered. -* -* @note None. -* -******************************************************************************/ -#define XASSERT_NONVOID_ALWAYS() \ -{ \ - XAssert(__FILE__, __LINE__); \ - XAssertStatus = XASSERT_OCCURRED; \ - return 0; \ -} - - -#else - -#define XASSERT_VOID(expression) -#define XASSERT_VOID_ALWAYS() -#define XASSERT_NONVOID(expression) -#define XASSERT_NONVOID_ALWAYS() -#endif - -/************************** Function Prototypes ******************************/ - -void XAssertSetCallback(XAssertCallback Routine); -void XNullHandler(void *NullParameter); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xdebug.h b/thirdparty/libxil/include/xilinx/xdebug.h deleted file mode 100644 index e8047e275..000000000 --- a/thirdparty/libxil/include/xilinx/xdebug.h +++ /dev/null @@ -1,93 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -#ifndef _XDEBUG_H -#define _XDEBUG_H - -#if defined(DEBUG) && !defined(NDEBUG) - -#include - -#ifndef XDEBUG_WARNING -#define XDEBUG_WARNING -#warning DEBUG is enabled -#endif - -#define XDBG_DEBUG_ERROR 0x00000001 /* error condition messages */ -#define XDBG_DEBUG_GENERAL 0x00000002 /* general debug messages */ -#define XDBG_DEBUG_ALL 0xFFFFFFFF /* all debugging data */ - -#define XDBG_DEBUG_FIFO_REG 0x00000100 /* display register reads/writes */ -#define XDBG_DEBUG_FIFO_RX 0x00000101 /* receive debug messages */ -#define XDBG_DEBUG_FIFO_TX 0x00000102 /* transmit debug messages */ -#define XDBG_DEBUG_FIFO_ALL 0x0000010F /* all fifo debug messages */ - -#define XDBG_DEBUG_TEMAC_REG 0x00000400 /* display register reads/writes */ -#define XDBG_DEBUG_TEMAC_RX 0x00000401 /* receive debug messages */ -#define XDBG_DEBUG_TEMAC_TX 0x00000402 /* transmit debug messages */ -#define XDBG_DEBUG_TEMAC_ALL 0x0000040F /* all temac debug messages */ - -#define XDBG_DEBUG_TEMAC_ADPT_RX 0x00000800 /* receive debug messages */ -#define XDBG_DEBUG_TEMAC_ADPT_TX 0x00000801 /* transmit debug messages */ -#define XDBG_DEBUG_TEMAC_ADPT_IOCTL 0x00000802 /* ioctl debug messages */ -#define XDBG_DEBUG_TEMAC_ADPT_MISC 0x00000803 /* debug msg for other routines */ -#define XDBG_DEBUG_TEMAC_ADPT_ALL 0x0000080F /* all temac adapter debug messages */ - -#define xdbg_current_types (XDBG_DEBUG_ERROR) - -#define xdbg_stmnt(x) x - -/* In VxWorks, if _WRS_GNU_VAR_MACROS is defined, special syntax is needed for - * macros that accept variable number of arguments - */ -#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS) -#define xdbg_printf(type, args...) (((type) & xdbg_current_types) ? printf (## args) : 0) - -#else /* ANSI Syntax */ - -#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0) - -#endif - -#else /* defined(DEBUG) && !defined(NDEBUG) */ - -#define xdbg_stmnt(x) - -/* See VxWorks comments above */ -#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS) -#define xdbg_printf(type, args...) -#else /* ANSI Syntax */ -#define xdbg_printf(...) -#endif - -#endif /* defined(DEBUG) && !defined(NDEBUG) */ - -#endif /* _XDEBUG_H */ diff --git a/thirdparty/libxil/include/xilinx/xenv.h b/thirdparty/libxil/include/xilinx/xenv.h deleted file mode 100644 index 54d24f476..000000000 --- a/thirdparty/libxil/include/xilinx/xenv.h +++ /dev/null @@ -1,191 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xenv.h -* @addtogroup common_v1_00_a -* @{ -* -* Defines common services that are typically found in a host operating. -* environment. This include file simply includes an OS specific file based -* on the compile-time constant BUILD_ENV_*, where * is the name of the target -* environment. -* -* All services are defined as macros. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00b ch   10/24/02 Added XENV_LINUX
-* 1.00a rmm  04/17/02 First release
-* 
-* -******************************************************************************/ - -#ifndef XENV_H /* prevent circular inclusions */ -#define XENV_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Select which target environment we are operating under - */ - -/* VxWorks target environment */ -#if defined XENV_VXWORKS -#include "xenv_vxworks.h" - -/* Linux target environment */ -#elif defined XENV_LINUX -#include "xenv_linux.h" - -/* Unit test environment */ -#elif defined XENV_UNITTEST -#include "ut_xenv.h" - -/* Integration test environment */ -#elif defined XENV_INTTEST -#include "int_xenv.h" - -/* Standalone environment selected */ -#else -#include "xenv_standalone.h" -#endif - - -/* - * The following comments specify the types and macro wrappers that are - * expected to be defined by the target specific header files - */ - -/**************************** Type Definitions *******************************/ - -/*****************************************************************************/ -/** - * - * XENV_TIME_STAMP - * - * A structure that contains a time stamp used by other time stamp macros - * defined below. This structure is processor dependent. - */ - - -/***************** Macros (Inline Functions) Definitions *********************/ - -/*****************************************************************************/ -/** - * - * XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes) - * - * Copies a non-overlapping block of memory. - * - * @param DestPtr is the destination address to copy data to. - * @param SrcPtr is the source address to copy data from. - * @param Bytes is the number of bytes to copy. - * - * @return None - */ - -/*****************************************************************************/ -/** - * - * XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes) - * - * Fills an area of memory with constant data. - * - * @param DestPtr is the destination address to set. - * @param Data contains the value to set. - * @param Bytes is the number of bytes to set. - * - * @return None - */ -/*****************************************************************************/ -/** - * - * XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) - * - * Samples the processor's or external timer's time base counter. - * - * @param StampPtr is the storage for the retrieved time stamp. - * - * @return None - */ - -/*****************************************************************************/ -/** - * - * XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) - * - * Computes the delta between the two time stamps. - * - * @param Stamp1Ptr - First sampled time stamp. - * @param Stamp1Ptr - Sedond sampled time stamp. - * - * @return An unsigned int value with units of microseconds. - */ - -/*****************************************************************************/ -/** - * - * XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) - * - * Computes the delta between the two time stamps. - * - * @param Stamp1Ptr - First sampled time stamp. - * @param Stamp1Ptr - Sedond sampled time stamp. - * - * @return An unsigned int value with units of milliseconds. - */ - -/*****************************************************************************//** - * - * XENV_USLEEP(unsigned delay) - * - * Delay the specified number of microseconds. - * - * @param delay is the number of microseconds to delay. - * - * @return None - */ - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ - -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xenv_linux.h b/thirdparty/libxil/include/xilinx/xenv_linux.h deleted file mode 100644 index e1edc618a..000000000 --- a/thirdparty/libxil/include/xilinx/xenv_linux.h +++ /dev/null @@ -1,255 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xenv_linux.h -* @addtogroup common_v1_00_a -* @{ -* -* Defines common services specified by xenv.h. -* -* @note -* This file is not intended to be included directly by driver code. -* Instead, the generic xenv.h file is intended to be included by driver -* code. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00a wgr  02/28/07 Added cache handling macros.
-* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
-* 1.00a xd   11/03/04 Improved support for doxygen.
-* 1.00a ch   10/24/02 First release
-* 1.10a wgr  03/22/07 Converted to new coding style.
-* 
-* -* -******************************************************************************/ - -#ifndef XENV_LINUX_H -#define XENV_LINUX_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/***************************** Include Files *********************************/ - -#include -#include -#include -#include - - -/****************************************************************************** - * - * MEMCPY / MEMSET related macros. - * - * Those macros are defined to catch legacy code in Xilinx drivers. The - * XENV_MEM_COPY and XENV_MEM_FILL macros were used in early Xilinx driver - * code. They are being replaced by memcpy() and memset() function calls. These - * macros are defined to catch any remaining occurences of those macros. - * - ******************************************************************************/ - -/*****************************************************************************/ -/** - * - * Copies a non-overlapping block of memory. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param SrcPtr - * Source address to copy data from. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - *****************************************************************************/ - -#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ - memcpy(DestPtr, SrcPtr, Bytes) -/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */ - - -/*****************************************************************************/ -/** - * - * Fills an area of memory with constant data. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param Data - * Value to set. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - *****************************************************************************/ - -#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ - memset(DestPtr, Data, Bytes) -/* do_not_use_XENV_MEM_FILL_use_memset_instead */ - - -/****************************************************************************** - * - * TIME related macros - * - ******************************************************************************/ -/** - * A structure that contains a time stamp used by other time stamp macros - * defined below. This structure is processor dependent. - */ -typedef int XENV_TIME_STAMP; - -/*****************************************************************************/ -/** - * - * Time is derived from the 64 bit PPC timebase register - * - * @param StampPtr is the storage for the retrieved time stamp. - * - * @return None. - * - * @note - * - * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) - *

- * This macro must be implemented by the user. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_GET(StampPtr) - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note - * - * This macro must be implemented by the user. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note - * - * This macro must be implemented by the user - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) - -/*****************************************************************************/ -/** - * - * Delay the specified number of microseconds. - * - * @param delay - * Number of microseconds to delay. - * - * @return None. - * - * @note XENV_USLEEP is deprecated. Use udelay() instead. - * - *****************************************************************************/ - -#define XENV_USLEEP(delay) udelay(delay) -/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */ - - -/****************************************************************************** - * - * CACHE handling macros / mappings - * - * The implementation of the cache handling functions can be found in - * arch/microblaze. - * - * These #defines are simple mappings to the Linux API. - * - * The underlying Linux implementation will take care of taking the right - * actions depending on the configuration of the MicroBlaze processor in the - * system. - * - ******************************************************************************/ - -#define XCACHE_ENABLE_DCACHE() __enable_dcache() -#define XCACHE_DISABLE_DCACHE() __disable_dcache() -#define XCACHE_ENABLE_ICACHE() __enable_icache() -#define XCACHE_DISABLE_ICACHE() __disable_icache() - -#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) invalidate_dcache_range((u32)(Addr), ((u32)(Addr)+(Len))) -#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) flush_dcache_range((u32)(Addr), ((u32)(Addr)+(Len))) - -#define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) "XCACHE_INVALIDATE_ICACHE_RANGE unsupported" -#define XCACHE_FLUSH_ICACHE_RANGE(Addr, Len) flush_icache_range(Addr, Len) - -#define XCACHE_ENABLE_CACHE() \ - { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } - -#define XCACHE_DISABLE_CACHE() \ - { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } - - - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ - -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xenv_none.h b/thirdparty/libxil/include/xilinx/xenv_none.h deleted file mode 100644 index e0ff47a01..000000000 --- a/thirdparty/libxil/include/xilinx/xenv_none.h +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xenv_none.h -* @addtogroup common_v1_00_a -* @{ -* -* This is a legacy file kept for backwards compatibility. -* -* Please modify your code to #include "xenv_standalone.h" instead. -* -* -******************************************************************************/ - -#warning ******************************************************************** -#warning * -#warning * Use of xenv_none.h deprecated. -#warning * Please include the new xenv_standalone.h file instead. -#warning * -#warning ******************************************************************** - -#include "xenv_standalone.h" - -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xenv_standalone.h b/thirdparty/libxil/include/xilinx/xenv_standalone.h deleted file mode 100644 index 14a83b05c..000000000 --- a/thirdparty/libxil/include/xilinx/xenv_standalone.h +++ /dev/null @@ -1,370 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xenv_standalone.h -* @addtogroup common_v1_00_a -* @{ -* -* Defines common services specified by xenv.h. -* -* @note -* This file is not intended to be included directly by driver code. -* Instead, the generic xenv.h file is intended to be included by driver -* code. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00a wgr  02/28/07 Added cache handling macros.
-* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
-* 1.00a rmm  01/24/06 Implemented XENV_USLEEP. Assume implementation is being
-*                     used under Xilinx standalone BSP.
-* 1.00a xd   11/03/04 Improved support for doxygen.
-* 1.00a rmm  03/21/02 First release
-* 1.00a wgr  03/22/07 Converted to new coding style.
-* 1.00a rpm  06/29/07 Added udelay macro for standalone
-* 1.00a xd   07/19/07 Included xparameters.h as XPAR_ constants are referred
-*                     to in MICROBLAZE section
-* 1.00a ecm  09/19/08 updated for v7.20 of Microblaze, new functionality
-*
-* 
-* -* -******************************************************************************/ - -#ifndef XENV_STANDALONE_H -#define XENV_STANDALONE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ -/****************************************************************************** - * - * Get the processor dependent includes - * - ******************************************************************************/ - -#include - -#if defined __MICROBLAZE__ -# include "mb_interface.h" -# include "xparameters.h" /* XPAR constants used below in MB section */ - -#elif defined __PPC__ -# include "sleep.h" -# include "xcache_l.h" /* also include xcache_l.h for caching macros */ -#endif - -/****************************************************************************** - * - * MEMCPY / MEMSET related macros. - * - * The following are straight forward implementations of memset and memcpy. - * - * NOTE: memcpy may not work if source and target memory area are overlapping. - * - ******************************************************************************/ -/*****************************************************************************/ -/** - * - * Copies a non-overlapping block of memory. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param SrcPtr - * Source address to copy data from. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - * @note - * The use of XENV_MEM_COPY is deprecated. Use memcpy() instead. - * - * @note - * This implemention MAY BREAK work if source and target memory - * area are overlapping. - * - *****************************************************************************/ - -#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ - memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes) - - - -/*****************************************************************************/ -/** - * - * Fills an area of memory with constant data. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param Data - * Value to set. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - * @note - * The use of XENV_MEM_FILL is deprecated. Use memset() instead. - * - *****************************************************************************/ - -#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ - memset((void *) DestPtr, (int) Data, (size_t) Bytes) - - - -/****************************************************************************** - * - * TIME related macros - * - ******************************************************************************/ - -/** - * A structure that contains a time stamp used by other time stamp macros - * defined below. This structure is processor dependent. - */ -typedef int XENV_TIME_STAMP; - -/*****************************************************************************/ -/** - * - * Time is derived from the 64 bit PPC timebase register - * - * @param StampPtr is the storage for the retrieved time stamp. - * - * @return None. - * - * @note - * - * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) - *

- * This macro must be implemented by the user. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_GET(StampPtr) - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note - * - * This macro must be implemented by the user. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note - * - * This macro must be implemented by the user. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) - -/*****************************************************************************/ -/** - * XENV_USLEEP(unsigned delay) - * - * Delay the specified number of microseconds. Not implemented without OS - * support. - * - * @param delay - * Number of microseconds to delay. - * - * @return None. - * - *****************************************************************************/ - -#ifdef __PPC__ -#define XENV_USLEEP(delay) usleep(delay) -#define udelay(delay) usleep(delay) -#else -#define XENV_USLEEP(delay) -#define udelay(delay) -#endif - - -/****************************************************************************** - * - * CACHE handling macros / mappings - * - ******************************************************************************/ -/****************************************************************************** - * - * Processor independent macros - * - ******************************************************************************/ - -#define XCACHE_ENABLE_CACHE() \ - { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } - -#define XCACHE_DISABLE_CACHE() \ - { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } - - -/****************************************************************************** - * - * MicroBlaze case - * - * NOTE: Currently the following macros will only work on systems that contain - * only ONE MicroBlaze processor. Also, the macros will only be enabled if the - * system is built using a xparameters.h file. - * - ******************************************************************************/ - -#if defined __MICROBLAZE__ - -/* Check if MicroBlaze data cache was built into the core. - */ -#if (XPAR_MICROBLAZE_USE_DCACHE == 1) -# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache() -# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache() -# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache() - -# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ - microblaze_invalidate_dcache_range((int)(Addr), (int)(Len)) - -#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1) -# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache() -# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ - microblaze_flush_dcache_range((int)(Addr), (int)(Len)) -#else -# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache() -# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ - microblaze_invalidate_dcache_range((int)(Addr), (int)(Len)) -#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/ - -#else -# define XCACHE_ENABLE_DCACHE() -# define XCACHE_DISABLE_DCACHE() -# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) -# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) -#endif /*XPAR_MICROBLAZE_USE_DCACHE*/ - - -/* Check if MicroBlaze instruction cache was built into the core. - */ -#if (XPAR_MICROBLAZE_USE_ICACHE == 1) -# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache() -# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache() - -# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache() - -# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \ - microblaze_invalidate_icache_range((int)(Addr), (int)(Len)) - -#else -# define XCACHE_ENABLE_ICACHE() -# define XCACHE_DISABLE_ICACHE() -#endif /*XPAR_MICROBLAZE_USE_ICACHE*/ - - -/****************************************************************************** - * - * PowerPC case - * - * Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a - * specific memory region (0x80000001). Each bit (0-30) in the regions - * bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB - * range. - * - * regions --> cached address range - * ------------|-------------------------------------------------- - * 0x80000000 | [0, 0x7FFFFFF] - * 0x00000001 | [0xF8000000, 0xFFFFFFFF] - * 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF] - * - ******************************************************************************/ - -#elif defined __PPC__ - -#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001) -#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache() -#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001) -#define XCACHE_DISABLE_ICACHE() XCache_DisableICache() - -#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ - XCache_InvalidateDCacheRange((unsigned int)(Addr), (unsigned)(Len)) - -#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ - XCache_FlushDCacheRange((unsigned int)(Addr), (unsigned)(Len)) - -#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache() - - -/****************************************************************************** - * - * Unknown processor / architecture - * - ******************************************************************************/ - -#else -/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */ -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* #ifndef XENV_STANDALONE_H */ - -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xenv_vxworks.h b/thirdparty/libxil/include/xilinx/xenv_vxworks.h deleted file mode 100644 index 1254a6bdc..000000000 --- a/thirdparty/libxil/include/xilinx/xenv_vxworks.h +++ /dev/null @@ -1,272 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xenv_vxworks.h -* @addtogroup common_v1_00_a -* @{ -* -* Defines common services specified by xenv.h. -* -* @note -* This file is not intended to be included directly by driver code. -* Instead, the generic xenv.h file is intended to be included by driver -* code. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00a wgr  02/28/07 Added cache handling macros.
-* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
-* 1.00a xd   11/03/04 Improved support for doxygen.
-*       rmm  09/13/03 CR 177068: Fix compiler warning in XENV_MEM_FILL
-*       rmm  10/24/02 Added XENV_USLEEP macro
-* 1.00a rmm  07/16/01 First release
-* 1.10a wgr  03/22/07 Converted to new coding style.
-* 
-* -* -******************************************************************************/ - -#ifndef XENV_VXWORKS_H -#define XENV_VXWORKS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xbasic_types.h" -#include "vxWorks.h" -#include "vxLib.h" -#include "sysLibExtra.h" -#include "cacheLib.h" -#include - -/*****************************************************************************/ -/** - * - * Copies a non-overlapping block of memory. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param SrcPtr - * Source address to copy data from. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - * @note XENV_MEM_COPY is deprecated. Use memcpy() instead. - * - *****************************************************************************/ - -#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ - memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes) - - -/*****************************************************************************/ -/** - * - * Fills an area of memory with constant data. - * - * @param DestPtr - * Destination address to copy data to. - * - * @param Data - * Value to set. - * - * @param Bytes - * Number of bytes to copy. - * - * @return None. - * - * @note XENV_MEM_FILL is deprecated. Use memset() instead. - * - *****************************************************************************/ - -#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ - memset((void *) DestPtr, (int) Data, (size_t) Bytes) - - -#if (CPU_FAMILY==PPC) -/** - * A structure that contains a time stamp used by other time stamp macros - * defined below. This structure is processor dependent. - */ -typedef struct -{ - u32 TimeBaseUpper; - u32 TimeBaseLower; -} XENV_TIME_STAMP; - -/*****************************************************************************/ -/** - * - * Time is derived from the 64 bit PPC timebase register - * - * @param StampPtr is the storage for the retrieved time stamp. - * - * @return None. - * - * @note - * - * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) - * - *****************************************************************************/ -#define XENV_TIME_STAMP_GET(StampPtr) \ -{ \ - vxTimeBaseGet((UINT32*)&(StampPtr)->TimeBaseUpper, \ - (UINT32*)&(StampPtr)->TimeBaseLower); \ -} - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note None. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) - -/*****************************************************************************/ -/** - * - * This macro is not yet implemented and always returns 0. - * - * @param Stamp1Ptr is the first sampled time stamp. - * @param Stamp2Ptr is the second sampled time stamp. - * - * @return 0 - * - * @note - * - * None. - * - *****************************************************************************/ -#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) - - -/* For non-PPC systems the above macros are not defined. Generate a error to - * make the developer aware of the problem. - */ -#else -#error "XENV_TIME_STAMP_GET used in a non-PPC system. Aborting." -#endif - - -/*****************************************************************************/ -/** - * - * Delay the specified number of microseconds. - * - * @param delay - * Number of microseconds to delay. - * - * @return None. - * - *****************************************************************************/ - -#define XENV_USLEEP(delay) sysUsDelay(delay) - -#define udelay(delay) sysUsDelay(delay) - - -/****************************************************************************** - * - * CACHE handling macros / mappings - * - ******************************************************************************/ -/****************************************************************************** - * - * PowerPC case - * - ******************************************************************************/ - -#if (CPU_FAMILY==PPC) - -#define XCACHE_ENABLE_CACHE() \ - { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } - -#define XCACHE_DISABLE_CACHE() \ - { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } - - -#define XCACHE_ENABLE_DCACHE() cacheEnable(DATA_CACHE) -#define XCACHE_DISABLE_DCACHE() cacheDisable(DATA_CACHE) -#define XCACHE_ENABLE_ICACHE() cacheEnable(INSTRUCTION_CACHE) -#define XCACHE_DISABLE_ICACHE() cacheDisable(INSTRUCTION_CACHE) - - -#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ - cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len)) - -#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ - cacheFlush(DATA_CACHE, (void *)(Addr), (Len)) - -#define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \ - cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len)) - -#define XCACHE_FLUSH_ICACHE_RANGE(Addr, Len) \ - cacheFlush(INSTRUCTION_CACHE, (void *)(Addr), (Len)) - - -/****************************************************************************** - * - * Unknown processor / architecture - * - ******************************************************************************/ - -#else -#error "Unknown processor / architecture. Must be PPC for VxWorks." -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* #ifdef XENV_VXWORKS_H */ - -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xhls_dft.h b/thirdparty/libxil/include/xilinx/xhls_dft.h deleted file mode 100644 index 42f6ae241..000000000 --- a/thirdparty/libxil/include/xilinx/xhls_dft.h +++ /dev/null @@ -1,77 +0,0 @@ -// ============================================================== -// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC -// Version: 2016.1 -// Copyright (C) 1986-2016 Xilinx, Inc. All Rights Reserved. -// -// ============================================================== - -#ifndef XHLS_DFT_H -#define XHLS_DFT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ -#include "xil_types.h" -#include "xil_assert.h" -#include "xstatus.h" -#include "xil_io.h" -#include "xhls_dft_hw.h" - -/**************************** Type Definitions ******************************/ -typedef struct { - u16 DeviceId; - u32 Ctrl_BaseAddress; -} XHls_dft_Config; - -typedef struct { - u32 Ctrl_BaseAddress; - u32 IsReady; -} XHls_dft; - -/***************** Macros (Inline Functions) Definitions *********************/ -#define XHls_dft_WriteReg(BaseAddress, RegOffset, Data) \ - Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data)) -#define XHls_dft_ReadReg(BaseAddress, RegOffset) \ - Xil_In32((BaseAddress) + (RegOffset)) - -/************************** Function Prototypes *****************************/ -int XHls_dft_Initialize(XHls_dft *InstancePtr, u16 DeviceId); -XHls_dft_Config* XHls_dft_LookupConfig(u16 DeviceId); -int XHls_dft_CfgInitialize(XHls_dft *InstancePtr, XHls_dft_Config *ConfigPtr); - -void XHls_dft_Start(XHls_dft *InstancePtr); -u32 XHls_dft_IsDone(XHls_dft *InstancePtr); -u32 XHls_dft_IsIdle(XHls_dft *InstancePtr); -u32 XHls_dft_IsReady(XHls_dft *InstancePtr); -void XHls_dft_EnableAutoRestart(XHls_dft *InstancePtr); -void XHls_dft_DisableAutoRestart(XHls_dft *InstancePtr); - -void XHls_dft_Set_num_harmonics_V(XHls_dft *InstancePtr, u32 Data); -u32 XHls_dft_Get_num_harmonics_V(XHls_dft *InstancePtr); -void XHls_dft_Set_decimation_V(XHls_dft *InstancePtr, u32 Data); -u32 XHls_dft_Get_decimation_V(XHls_dft *InstancePtr); -u32 XHls_dft_Get_fharmonics_BaseAddress(XHls_dft *InstancePtr); -u32 XHls_dft_Get_fharmonics_HighAddress(XHls_dft *InstancePtr); -u32 XHls_dft_Get_fharmonics_TotalBytes(XHls_dft *InstancePtr); -u32 XHls_dft_Get_fharmonics_BitWidth(XHls_dft *InstancePtr); -u32 XHls_dft_Get_fharmonics_Depth(XHls_dft *InstancePtr); -u32 XHls_dft_Write_fharmonics_Words(XHls_dft *InstancePtr, int offset, int *data, int length); -u32 XHls_dft_Read_fharmonics_Words(XHls_dft *InstancePtr, int offset, int *data, int length); -u32 XHls_dft_Write_fharmonics_Bytes(XHls_dft *InstancePtr, int offset, char *data, int length); -u32 XHls_dft_Read_fharmonics_Bytes(XHls_dft *InstancePtr, int offset, char *data, int length); - -void XHls_dft_InterruptGlobalEnable(XHls_dft *InstancePtr); -void XHls_dft_InterruptGlobalDisable(XHls_dft *InstancePtr); -void XHls_dft_InterruptEnable(XHls_dft *InstancePtr, u32 Mask); -void XHls_dft_InterruptDisable(XHls_dft *InstancePtr, u32 Mask); -void XHls_dft_InterruptClear(XHls_dft *InstancePtr, u32 Mask); -u32 XHls_dft_InterruptGetEnabled(XHls_dft *InstancePtr); -u32 XHls_dft_InterruptGetStatus(XHls_dft *InstancePtr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libxil/include/xilinx/xhls_dft_hw.h b/thirdparty/libxil/include/xilinx/xhls_dft_hw.h deleted file mode 100644 index ff3cedc18..000000000 --- a/thirdparty/libxil/include/xilinx/xhls_dft_hw.h +++ /dev/null @@ -1,52 +0,0 @@ -// ============================================================== -// File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC -// Version: 2016.1 -// Copyright (C) 1986-2016 Xilinx, Inc. All Rights Reserved. -// -// ============================================================== - -// ctrl -// 0x00 : Control signals -// bit 0 - ap_start (Read/Write/COH) -// bit 1 - ap_done (Read/COR) -// bit 2 - ap_idle (Read) -// bit 3 - ap_ready (Read) -// bit 7 - auto_restart (Read/Write) -// others - reserved -// 0x04 : Global Interrupt Enable Register -// bit 0 - Global Interrupt Enable (Read/Write) -// others - reserved -// 0x08 : IP Interrupt Enable Register (Read/Write) -// bit 0 - Channel 0 (ap_done) -// bit 1 - Channel 1 (ap_ready) -// others - reserved -// 0x0c : IP Interrupt Status Register (Read/TOW) -// bit 0 - Channel 0 (ap_done) -// bit 1 - Channel 1 (ap_ready) -// others - reserved -// 0x80 : Data signal of num_harmonics_V -// bit 7~0 - num_harmonics_V[7:0] (Read/Write) -// others - reserved -// 0x84 : reserved -// 0x88 : Data signal of decimation_V -// bit 7~0 - decimation_V[7:0] (Read/Write) -// others - reserved -// 0x8c : reserved -// 0x40 ~ -// 0x7f : Memory 'fharmonics' (16 * 32b) -// Word n : bit [31:0] - fharmonics[n] -// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake) - -#define XHLS_DFT_CTRL_ADDR_AP_CTRL 0x00 -#define XHLS_DFT_CTRL_ADDR_GIE 0x04 -#define XHLS_DFT_CTRL_ADDR_IER 0x08 -#define XHLS_DFT_CTRL_ADDR_ISR 0x0c -#define XHLS_DFT_CTRL_ADDR_NUM_HARMONICS_V_DATA 0x80 -#define XHLS_DFT_CTRL_BITS_NUM_HARMONICS_V_DATA 8 -#define XHLS_DFT_CTRL_ADDR_DECIMATION_V_DATA 0x88 -#define XHLS_DFT_CTRL_BITS_DECIMATION_V_DATA 8 -#define XHLS_DFT_CTRL_ADDR_FHARMONICS_BASE 0x40 -#define XHLS_DFT_CTRL_ADDR_FHARMONICS_HIGH 0x7f -#define XHLS_DFT_CTRL_WIDTH_FHARMONICS 32 -#define XHLS_DFT_CTRL_DEPTH_FHARMONICS 16 - diff --git a/thirdparty/libxil/include/xilinx/xil_assert.h b/thirdparty/libxil/include/xilinx/xil_assert.h deleted file mode 100644 index 7ce034201..000000000 --- a/thirdparty/libxil/include/xilinx/xil_assert.h +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xil_assert.h -* -* This file contains assert related functions. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who    Date   Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a hbm  07/14/09 First release
-* 
-* -******************************************************************************/ - -#ifndef XIL_ASSERT_H /* prevent circular inclusions */ -#define XIL_ASSERT_H /* by using protection macros */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/***************************** Include Files *********************************/ - - -/************************** Constant Definitions *****************************/ - -/***************** Macros (Inline Functions) Definitions *********************/ - -#define Xil_AssertVoid(expr) \ - ((expr) \ - ? __ASSERT_VOID_CAST (0) \ - : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION)) -#define Xil_AssertNonvoid(expr) \ - ((expr) \ - ? __ASSERT_VOID_CAST (0) \ - : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION)) -#define Xil_AssertVoidAlways() \ - __assert_fail ("always", __FILE__, __LINE__, __ASSERT_FUNCTION) -#define Xil_AssertNonvoidAlways() \ - __assert_fail ("always", __FILE__, __LINE__, __ASSERT_FUNCTION) - -/************************** Function Prototypes ******************************/ - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ diff --git a/thirdparty/libxil/include/xilinx/xil_cache.h b/thirdparty/libxil/include/xilinx/xil_cache.h deleted file mode 100644 index a1b68faf0..000000000 --- a/thirdparty/libxil/include/xilinx/xil_cache.h +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xil_cache.h -* -* Contains dummies for cache related functions. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date	 Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a hbm  12/11/09 Initial release
-*
-* 
-* -* @note -* -******************************************************************************/ - -#ifndef XIL_CACHE_VXWORKS_H -#define XIL_CACHE_VXWORKS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define Xil_DCacheEnable() -#define Xil_DCacheDisable() -#define Xil_DCacheInvalidateRange(Addr, Len) -#define Xil_DCacheFlushRange(Addr, Len) -#define Xil_ICacheEnable() -#define Xil_ICacheDisable() -#define Xil_ICacheInvalidateRange(Addr, Len) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libxil/include/xilinx/xil_io.h b/thirdparty/libxil/include/xilinx/xil_io.h deleted file mode 100644 index ae35ff60b..000000000 --- a/thirdparty/libxil/include/xilinx/xil_io.h +++ /dev/null @@ -1,246 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xil_io.h -* -* This file contains the interface for the general IO component, which -* encapsulates the Input/Output functions for processors that do not -* require any special I/O handling. -* -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who      Date     Changes
-* ----- -------- -------- -----------------------------------------------
-* 1.00a ecm/sdm  10/24/09 First release
-* 1.00a sdm      07/21/10 Added Xil_Htonl/s, Xil_Ntohl/s
-* 3.07a asa	     08/31/12 Added xil_printf.h include
-* 3.08a sgd	     11/05/12 Reverted SYNC macros definitions
-* 
-******************************************************************************/ - -#ifndef XIL_IO_H /* prevent circular inclusions */ -#define XIL_IO_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_types.h" -//#include "xpseudo_asm.h" -#include "xil_printf.h" - -/************************** Constant Definitions *****************************/ - -/**************************** Type Definitions *******************************/ - -/***************** Macros (Inline Functions) Definitions *********************/ - -#if 0 -# define SYNCHRONIZE_IO dmb() -# define INST_SYNC isb() -# define DATA_SYNC dsb() -#else -# define SYNCHRONIZE_IO -# define INST_SYNC -# define DATA_SYNC -#endif /* __GNUC__ */ - -/*****************************************************************************/ -/** -* -* Perform an big-endian input operation for a 16-bit memory location -* by reading from the specified address and returning the Value read from -* that address. -* -* @param Addr contains the address to perform the input operation at. -* -* @return The Value read from the specified input address with the -* proper endianness. The return Value has the same endianness -* as that of the processor, i.e. if the processor is -* little-engian, the return Value is the byte-swapped Value read -* from the address. -* -* @note None. -* -******************************************************************************/ -#define Xil_In16LE(Addr) Xil_In16((Addr)) - -/*****************************************************************************/ -/** -* -* Perform a big-endian input operation for a 32-bit memory location -* by reading from the specified address and returning the Value read from -* that address. -* -* @param Addr contains the address to perform the input operation at. -* -* @return The Value read from the specified input address with the -* proper endianness. The return Value has the same endianness -* as that of the processor, i.e. if the processor is -* little-engian, the return Value is the byte-swapped Value read -* from the address. -* -* -* @note None. -* -******************************************************************************/ -#define Xil_In32LE(Addr) Xil_In32((Addr)) - -/*****************************************************************************/ -/** -* -* Perform a big-endian output operation for a 16-bit memory location -* by writing the specified Value to the specified address. -* -* @param Addr contains the address to perform the output operation at. -* @param Value contains the Value to be output at the specified address. -* The Value has the same endianness as that of the processor. -* If the processor is little-endian, the byte-swapped Value is -* written to the address. -* -* -* @return None -* -* @note None. -* -******************************************************************************/ -#define Xil_Out16LE(Addr, Value) Xil_Out16((Addr), (Value)) - -/*****************************************************************************/ -/** -* -* Perform a big-endian output operation for a 32-bit memory location -* by writing the specified Value to the specified address. -* -* @param Addr contains the address to perform the output operation at. -* @param Value contains the Value to be output at the specified address. -* The Value has the same endianness as that of the processor. -* If the processor is little-endian, the byte-swapped Value is -* written to the address. -* -* @return None -* -* @note None. -* -******************************************************************************/ -#define Xil_Out32LE(Addr, Value) Xil_Out32((Addr), (Value)) - -/*****************************************************************************/ -/** -* -* Convert a 32-bit number from host byte order to network byte order. -* -* @param Data the 32-bit number to be converted. -* -* @return The converted 32-bit number in network byte order. -* -* @note None. -* -******************************************************************************/ -#define Xil_Htonl(Data) Xil_EndianSwap32((Data)) - -/*****************************************************************************/ -/** -* -* Convert a 16-bit number from host byte order to network byte order. -* -* @param Data the 16-bit number to be converted. -* -* @return The converted 16-bit number in network byte order. -* -* @note None. -* -******************************************************************************/ -#define Xil_Htons(Data) Xil_EndianSwap16((Data)) - -/*****************************************************************************/ -/** -* -* Convert a 32-bit number from network byte order to host byte order. -* -* @param Data the 32-bit number to be converted. -* -* @return The converted 32-bit number in host byte order. -* -* @note None. -* -******************************************************************************/ -#define Xil_Ntohl(Data) Xil_EndianSwap32((Data)) - -/*****************************************************************************/ -/** -* -* Convert a 16-bit number from network byte order to host byte order. -* -* @param Data the 16-bit number to be converted. -* -* @return The converted 16-bit number in host byte order. -* -* @note None. -* -******************************************************************************/ -#define Xil_Ntohs(Data) Xil_EndianSwap16((Data)) - -/************************** Function Prototypes ******************************/ - -/* The following functions allow the software to be transportable across - * processors which may use memory mapped I/O or I/O which is mapped into a - * seperate address space. - */ -u8 Xil_In8(INTPTR Addr); -u16 Xil_In16(INTPTR Addr); -u32 Xil_In32(INTPTR Addr); - -void Xil_Out8(INTPTR Addr, u8 Value); -void Xil_Out16(INTPTR Addr, u16 Value); -void Xil_Out32(INTPTR Addr, u32 Value); - - -u16 Xil_In16BE(INTPTR Addr); -u32 Xil_In32BE(INTPTR Addr); -void Xil_Out16BE(INTPTR Addr, u16 Value); -void Xil_Out32BE(INTPTR Addr, u32 Value); - -u16 Xil_EndianSwap16(u16 Data); -u32 Xil_EndianSwap32(u32 Data); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ diff --git a/thirdparty/libxil/include/xilinx/xil_printf.h b/thirdparty/libxil/include/xilinx/xil_printf.h deleted file mode 100644 index a3ecfea50..000000000 --- a/thirdparty/libxil/include/xilinx/xil_printf.h +++ /dev/null @@ -1,43 +0,0 @@ - #ifndef XIL_PRINTF_H - #define XIL_PRINTF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include "xil_types.h" - -/*----------------------------------------------------*/ -/* Use the following parameter passing structure to */ -/* make xil_printf re-entrant. */ -/*----------------------------------------------------*/ - -struct params_s; - - -/*---------------------------------------------------*/ -/* The purpose of this routine is to output data the */ -/* same as the standard printf function without the */ -/* overhead most run-time libraries involve. Usually */ -/* the printf brings in many kilobytes of code and */ -/* that is unacceptable in most embedded systems. */ -/*---------------------------------------------------*/ - -typedef char8* charptr; -typedef s32 (*func_ptr)(int c); - -#define xil_printf(fmt, ...) printf(fmt, ##__VA_ARGS__) -#define print(ptr) printf("%s", ptr) - -#define outbyte(byte) putc(byte, stdout) -#define inbyte(); getc(stdin) - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ diff --git a/thirdparty/libxil/include/xilinx/xil_types.h b/thirdparty/libxil/include/xilinx/xil_types.h deleted file mode 100644 index e8b78b7c6..000000000 --- a/thirdparty/libxil/include/xilinx/xil_types.h +++ /dev/null @@ -1,200 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xil_types.h -* -* This file contains basic types for Xilinx software IP. - -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who    Date   Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a hbm  07/14/09 First release
-* 3.03a sdm  05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
-* 5.00 	pkp  05/29/14 Made changes for 64 bit architecture
-*	srt  07/14/14 Use standard definitions from stdint.h and stddef.h
-*		      Define LONG and ULONG datatypes and mask values
-* 
-* -******************************************************************************/ - -#ifndef XIL_TYPES_H /* prevent circular inclusions */ -#define XIL_TYPES_H /* by using protection macros */ - -#include -#include - -/************************** Constant Definitions *****************************/ - -#ifndef TRUE -# define TRUE 1U -#endif - -#ifndef FALSE -# define FALSE 0U -#endif - -#ifndef NULL -#define NULL 0U -#endif - -#define XIL_COMPONENT_IS_READY 0x11111111U /**< component has been initialized */ -#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< component has been started */ - -/** @name New types - * New simple types. - * @{ - */ -#ifndef __KERNEL__ -#ifndef XBASIC_TYPES_H -/** - * guarded against xbasic_types.h. - */ -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; - -#define __XUINT64__ -typedef struct -{ - u32 Upper; - u32 Lower; -} Xuint64; - - -/*****************************************************************************/ -/** -* Return the most significant half of the 64 bit data type. -* -* @param x is the 64 bit word. -* -* @return The upper 32 bits of the 64 bit word. -* -* @note None. -* -******************************************************************************/ -#define XUINT64_MSW(x) ((x).Upper) - -/*****************************************************************************/ -/** -* Return the least significant half of the 64 bit data type. -* -* @param x is the 64 bit word. -* -* @return The lower 32 bits of the 64 bit word. -* -* @note None. -* -******************************************************************************/ -#define XUINT64_LSW(x) ((x).Lower) - -#endif /* XBASIC_TYPES_H */ - -/** - * xbasic_types.h does not typedef s* or u64 - */ - -typedef char char8; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; -typedef uint64_t u64; -typedef int sint32; - -typedef intptr_t INTPTR; -typedef uintptr_t UINTPTR; -typedef ptrdiff_t PTRDIFF; - -#if !defined(LONG) || !defined(ULONG) -typedef long LONG; -typedef unsigned long ULONG; -#endif - -#define ULONG64_HI_MASK 0xFFFFFFFF00000000U -#define ULONG64_LO_MASK ~ULONG64_HI_MASK - -#else -#include -#endif - - -/** - * This data type defines an interrupt handler for a device. - * The argument points to the instance of the component - */ -typedef void (*XInterruptHandler) (void *InstancePtr); - -/** - * This data type defines an exception handler for a processor. - * The argument points to the instance of the component - */ -typedef void (*XExceptionHandler) (void *InstancePtr); - -/** - * UPPER_32_BITS - return bits 32-63 of a number - * @n: the number we're accessing - * - * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress - * the "right shift count >= width of type" warning when that quantity is - * 32-bits. - */ -#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16)) - -/** - * LOWER_32_BITS - return bits 0-31 of a number - * @n: the number we're accessing - */ -#define LOWER_32_BITS(n) ((u32)(n)) - -/*@}*/ - - -/************************** Constant Definitions *****************************/ - -#ifndef TRUE -#define TRUE 1U -#endif - -#ifndef FALSE -#define FALSE 0U -#endif - -#ifndef NULL -#define NULL 0U -#endif - -#endif /* end of protection macro */ diff --git a/thirdparty/libxil/include/xilinx/xintc.h b/thirdparty/libxil/include/xilinx/xintc.h deleted file mode 100644 index 080f01b51..000000000 --- a/thirdparty/libxil/include/xilinx/xintc.h +++ /dev/null @@ -1,370 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xintc.h -* @addtogroup intc_v3_4 -* @{ -* @details -* -* The Xilinx interrupt controller driver component. This component supports the -* Xilinx interrupt controller. -* -* The interrupt controller driver uses the idea of priority for the various -* handlers. Priority is an integer within the range of 0 and 31 inclusive with -* 0 being the highest priority interrupt source. -* -* The Xilinx interrupt controller supports the following features: -* -* - specific individual interrupt enabling/disabling -* - specific individual interrupt acknowledging -* - attaching specific callback function to handle interrupt source -* - master enable/disable -* - single callback per interrupt or all pending interrupts handled for -* each interrupt of the processor -* -* The acknowledgement of the interrupt within the interrupt controller is -* selectable, either prior to the device's handler being called or after -* the handler is called. This is necessary to support interrupt signal inputs -* which are either edge or level signals. Edge driven interrupt signals -* require that the interrupt is acknowledged prior to the interrupt being -* serviced in order to prevent the loss of interrupts which are occurring -* extremely close together. A level driven interrupt input signal requires -* the interrupt to acknowledged after servicing the interrupt to ensure that -* the interrupt only generates a single interrupt condition. -* -* Details about connecting the interrupt handler of the driver are contained -* in the source file specific to interrupt processing, xintc_intr.c. -* -* This driver is intended to be RTOS and processor independent. It works with -* physical addresses only. Any needs for dynamic memory management, threads -* or thread mutual exclusion, virtual memory, or cache control must be -* satisfied by the layer above this driver. -* -* Interrupt Vector Tables -* -* The interrupt vector table for each interrupt controller device is declared -* statically in xintc_g.c within the configuration data for each instance. -* The device ID of the interrupt controller device is used by the driver as a -* direct index into the configuration data table - to retrieve the vector table -* for an instance of the interrupt controller. The user should populate the -* vector table with handlers and callbacks at run-time using the XIntc_Connect() -* and XIntc_Disconnect() functions. -* -* Each vector table entry corresponds to a device that can generate an -* interrupt. Each entry contains an interrupt handler function and an argument -* to be passed to the handler when an interrupt occurs. The tools default this -* argument to the base address of the interrupting device. Note that the -* device driver interrupt handlers given in this file do not take a base -* address as an argument, but instead take a pointer to the driver instance. -* This means that although the table is created statically, the user must still -* use XIntc_Connect() when the interrupt handler takes an argument other than -* the base address. This is only to say that the existence of the static vector -* tables should not mislead the user into thinking they no longer need to -* register/connect interrupt handlers with this driver. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a ecm  08/16/01 First release
-* 1.00a rpm  01/09/02 Removed the AckLocation argument from XIntc_Connect().
-*                     This information is now internal in xintc_g.c.
-* 1.00b jhl  02/13/02 Repartitioned the driver for smaller files
-* 1.00b jhl  04/24/02 Made LookupConfig function global and relocated config
-*                     data type
-* 1.00c rpm  10/17/03 New release. Support the static vector table created
-*                     in the xintc_g.c configuration table. Moved vector
-*                     table and options out of instance structure and into
-*                     the configuration table.
-* 1.10c mta  03/21/07 Updated to new coding style
-* 1.11a sv   11/21/07 Updated driver to support access through a DCR bridge
-* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs and _m is removed from
-*		      all the macro names/definitions.
-* 2.01a sdm  04/27/10 Updated the tcl so that the defintions are generated in
-*		      the xparameters.h to know whether the optional registers
-*		      SIE, CIE and IVR are enabled in the HW - Refer CR 555392.
-*		      This driver doesnot make use of these definitions and does
-*		      not use the optional registers.
-* 2.03a hvm  05/24/11 Updated the tcl to generate vector Ids for external
-*		      interrupts. CR565336
-* 2.04a bss  01/13/12 Added XIntc_ConnectFastHandler API for Fast Interrupt
-*		      and XIntc_SetNormalIntrMode for setting to normal
-*		      interrupt mode.
-* 2.04a asa  03/19/12 Changed the XIntc_Config struct. The order of entries
-*		      declared in the structure now matches with the
-*		      XIntc_ConfigTable generated by the driver tcl.
-* 2.05a bss  08/16/12 Updated to support relocatable vectors in Microblaze,
-*		      added IntVectorAddr to XIntc_Config for this.
-*		      Added XIntc_RegisterFastHandler API to register fast
-*		      interrupt handlers using base address.
-* 2.06a bss  01/28/13 To support Cascade mode:
-* 		      Added XIN_INTC_NOCASCADE,XIN_INTC_PRIMARY,
-*		      XIN_INTC_SECONDARY,XIN_INTC_LAST and
-*		      XIN_CONTROLLER_MAX_INTRS  macros
-*		      Added NumberofIntrs and IntcType fields in XIntc_Config
-*		      structure.
-*		      Modified XIntc_Initialize,XIntc_Start,XIntc_Connect
-*		      XIntc_Disconnect,XIntc_Enable,XIntc_Disable,
-*		      XIntc_Acknowledge,XIntc_ConnectFastHandler and
-*		      XIntc_SetNormalIntrMode APIs.Added XIntc_InitializeSlaves
-*		      API in xintc.c
-*  		      Modified XIntc_DeviceInterruptHandler,
-*  		      XIntc_SetIntrSvcOption,XIntc_RegisterHandler and
-*		      XIntc_RegisterFastHandler APIs.Added XIntc_CascadeHandler
-*		      API in xintc_l.c.
-*		      Modified XIntc_SetOptions API in xintc_options.c.
-*		      Modified XIntc_SimulateIntr API in xintc_selftest.c.
-*		      Modified driver tcl:
-*			to check for Cascade mode and generate XPAR_INTC_TYPE
-*			for each controller.
-*			Generate XPAR_INTC_MAX_NUM_INTR_INPUTS by adding all
-*			interrupt sources of all Controllers in Cascade mode.
-* 2.07a bss  10/18/13 To support Nested interrupts:
-*		      Modified XIntc_DeviceInterruptHandler API.
-*		      Added XIN_ILR_OFFSET macro in xintc_l.h.
-*		      Modified driver tcl to generate HAS_ILR parameter in
-*		      xparameters.h
-* 3.0   bss  01/28/13 Modified xintc.c to initialize IVAR register with
-*		      XPAR_MICROBLAZE_BASE_VECTORS + 0x10 to fix
-*		      CR#765931.
-*		      Modified driver tcl to generate XPAR_AXI_INTC_0_TYPE
-*		      correctly(CR#764865).
-*
-* @note
-*		For Cascade mode, Interrupt IDs are generated in xparameters.h
-*		as shown below:
-*
-*	    Master/Primary INTC
-*		 ______
-*		|      |-0      Secondary INTC
-*		|      |-.         ______
-*		|      |-.        |      |-32        Last INTC
-*		|      |-.        |      |-.          ______
-*		|______|<-31------|      |-.         |      |-64
-*			          |      |-.         |      |-.
-*			          |______|<-63-------|      |-.
-*                                                    |      |-.
-*                                                    |______|-95
-*
-*		All driver functions has to be called using DeviceId/
-*		InstancePtr/BaseAddress of Primary/Master Controller and
-*		Interrupts IDs generated in xparameters.h only.
-*		Driver functions takes care of Slave Controllers based on
-*		Interrupt ID passed. User must not use Interrupt source/ID
-*		31 of Primary and Secondary controllers to call driver
-*		functions.
-*
-*		For nested interrupts, XIntc_DeviceInterruptHandler saves
-*		microblaze r14 register on entry and restores on exit. This is
-*		required since compiler does not support nesting. It enables
-*		Microblaze interrupts after blocking further interrupts from
-*		the current interrupt number and interrupts below current
-*		interrupt proirity by writing to Interrupt Level Register of
-*		INTC on entry. On exit, it disables microblaze interrupts and
-*		restores ILR register default value(0xFFFFFFFF)back. It is
-*		recommended to increase STACK_SIZE in linker script for nested
-*		interrupts.
-* 3.0     adk    12/10/13  Updated as per the New Tcl API's
-* 3.0 	  adk 	 17/02/14  Fixed the CR:771287 Changes are made in the intc
-* 		           driver tcl.
-* 3.1     adk    8/4/14    Fixed the CR:783248 Changes are made in
-*			   the test-app tcl
-* 3.2     bss    4/8/14    Fixed driver tcl to handle external interrupt pins
-*			   correctly (CR#799609).
-* 3.3     adk    11/3/14   added generation of C_HAS_ILR parameter to
-*			   xparameters.h.Changes are made in the driver tcl file
-*			   (CR#828046).
-*
-* 
-* -******************************************************************************/ - -#ifndef XINTC_H /* prevent circular inclusions */ -#define XINTC_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/***************************** Include Files *********************************/ - -#include "xil_types.h" -#include "xil_assert.h" -#include "xparameters.h" -#include "xstatus.h" -#include "xintc_l.h" - -/************************** Constant Definitions *****************************/ - -/** - * @name Configuration options - * These options are used in XIntc_SetOptions() to configure the device. - * @{ - */ -/** - *
- * XIN_SVC_SGL_ISR_OPTION	Service the highest priority pending interrupt
- *				and then return.
- * XIN_SVC_ALL_ISRS_OPTION	Service all of the pending interrupts and then
- *				return.
- * 
- */ -#define XIN_SVC_SGL_ISR_OPTION 1UL -#define XIN_SVC_ALL_ISRS_OPTION 2UL -/*@}*/ - -/** - * @name Start modes - * One of these values is passed to XIntc_Start() to start the device. - * @{ - */ -/** Simulation only mode, no hardware interrupts recognized */ -#define XIN_SIMULATION_MODE 0 -/** Real mode, no simulation allowed, hardware interrupts recognized */ -#define XIN_REAL_MODE 1 -/*@}*/ - -/** - * @name Masks to specify Interrupt Controller Mode - * @{ - */ -#define XIN_INTC_NOCASCADE 0 /* Normal - No Cascade Mode */ -#define XIN_INTC_PRIMARY 1 /* Master/Primary controller */ -#define XIN_INTC_SECONDARY 2 /* Secondary Slave Controllers */ -#define XIN_INTC_LAST 3 /* Last Slave Controller */ - -/*@}*/ - -/** - * @name Mask to specify maximum number of interrupt sources per controller - * @{ - */ -#define XIN_CONTROLLER_MAX_INTRS 32 /* Each Controller has 32 - interrupt pins */ -/*@}*/ - -/**************************** Type Definitions *******************************/ - -/** - * This typedef contains configuration information for the device. - */ -typedef struct { - u16 DeviceId; /**< Unique ID of device */ - u32 BaseAddress; /**< Register base address */ - u32 AckBeforeService; /**< Ack location per interrupt */ - int FastIntr; /**< Fast Interrupt enabled */ - u32 IntVectorAddr; /**< Interrupt Vector Address */ - int NumberofIntrs; /**< Number of Interrupt sources */ - u32 Options; /**< Device options */ - int IntcType; /**< Intc type 0 - No Cascade Mode - 1 - primary instance - 2 - secondary instance - 3 - last instance */ - -/** Static vector table of interrupt handlers */ -#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE - XIntc_VectorTableEntry HandlerTable[XIN_CONTROLLER_MAX_INTRS]; -#else - XIntc_VectorTableEntry HandlerTable[XPAR_INTC_MAX_NUM_INTR_INPUTS]; -#endif - -} XIntc_Config; - -/** - * The XIntc driver instance data. The user is required to allocate a - * variable of this type for every intc device in the system. A pointer - * to a variable of this type is then passed to the driver API functions. - */ -typedef struct { - u32 BaseAddress; /**< Base address of registers */ - u32 IsReady; /**< Device is initialized and ready */ - u32 IsStarted; /**< Device has been started */ - u32 UnhandledInterrupts; /**< Intc Statistics */ - XIntc_Config *CfgPtr; /**< Pointer to instance config entry */ - -} XIntc; - -/***************** Macros (Inline Functions) Definitions *********************/ - -/************************** Function Prototypes ******************************/ - -/* - * Required functions in xintc.c - */ -int XIntc_Initialize(XIntc * InstancePtr, u16 DeviceId); - -int XIntc_Start(XIntc * InstancePtr, u8 Mode); -void XIntc_Stop(XIntc * InstancePtr); - -int XIntc_Connect(XIntc * InstancePtr, u8 Id, - XInterruptHandler Handler, void *CallBackRef); -void XIntc_Disconnect(XIntc * InstancePtr, u8 Id); - -void XIntc_Enable(XIntc * InstancePtr, u8 Id); -void XIntc_Disable(XIntc * InstancePtr, u8 Id); - -void XIntc_Acknowledge(XIntc * InstancePtr, u8 Id); - -XIntc_Config *XIntc_LookupConfig(u16 DeviceId); - -int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id, - XFastInterruptHandler Handler); -void XIntc_SetNormalIntrMode(XIntc *InstancePtr, u8 Id); - -/* - * Interrupt functions in xintr_intr.c - */ -void XIntc_VoidInterruptHandler(void); -void XIntc_InterruptHandler(XIntc * InstancePtr); - -/* - * Options functions in xintc_options.c - */ -int XIntc_SetOptions(XIntc * InstancePtr, u32 Options); -u32 XIntc_GetOptions(XIntc * InstancePtr); - -/* - * Self-test functions in xintc_selftest.c - */ -int XIntc_SelfTest(XIntc * InstancePtr); -int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xintc_l.h b/thirdparty/libxil/include/xilinx/xintc_l.h deleted file mode 100644 index 9d9c9eaff..000000000 --- a/thirdparty/libxil/include/xilinx/xintc_l.h +++ /dev/null @@ -1,330 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xintc_l.h -* @addtogroup intc_v3_4 -* @{ -* -* This header file contains identifiers and low-level driver functions (or -* macros) that can be used to access the device. The user should refer to the -* hardware device specification for more details of the device operation. -* -* -* Note that users of the driver interface given in this file can register -* an interrupt handler dynamically (at run-time) using the -* XIntc_RegisterHandler() function. -* User of the driver interface given in xintc.h should still use -* XIntc_Connect(), as always. -* Also see the discussion of the interrupt vector tables in xintc.h. -* -* There are currently two interrupt handlers specified in this interface. -* -* - XIntc_LowLevelInterruptHandler() is a handler without any arguments that -* is used in cases where there is a single interrupt controller device in -* the system and the handler cannot be passed an argument. This function is -* provided mostly for backward compatibility. -* -* - XIntc_DeviceInterruptHandler() is a handler that takes a device ID as an -* argument, indicating which interrupt controller device in the system is -* causing the interrupt - thereby supporting multiple interrupt controllers. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------------
-* 1.00b jhl  04/24/02 First release
-* 1.00c rpm  10/17/03 New release. Support the static vector table created
-*                     in the xintc_g.c configuration table.
-* 1.10c mta  03/21/07 Updated to new coding style
-* 1.11a sv   11/21/07 Updated driver to support access through a DCR bridge
-* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. _m is removed from all
-*		      the macro definitions.
-* 2.04a bss  01/13/12 Updated for adding defines for IMR and IVAR for
-*                     the FAST Interrupt
-* 2.05a bss  08/18/12 Added XIntc_RegisterFastHandler API to register fast
-*		      interrupt handlers using base address.
-* 2.07a bss  10/18/13 Added XIN_ILR_OFFSET macro for nested interrupts.
-*
-* 
-* -******************************************************************************/ - -#ifndef XINTC_L_H /* prevent circular inclusions */ -#define XINTC_L_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_types.h" -#include "xil_assert.h" -#include "xparameters.h" -#include "xil_io.h" - -/* - * XPAR_XINTC_USE_DCR_BRIDGE has to be set to 1 if the Intc device will be - * accessed through a DCR bus connected to a bridge. - */ -#define XPAR_XINTC_USE_DCR_BRIDGE 0 - -#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) -#include "xio_dcr.h" -#endif - -/************************** Constant Definitions *****************************/ - -/* define the offsets from the base address for all the registers of the - * interrupt controller, some registers may be optional in the hardware device - */ -#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) - -#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */ -#define XIN_IPR_OFFSET 1 /* Interrupt Pending Register */ -#define XIN_IER_OFFSET 2 /* Interrupt Enable Register */ -#define XIN_IAR_OFFSET 3 /* Interrupt Acknowledge Register */ -#define XIN_SIE_OFFSET 4 /* Set Interrupt Enable Register */ -#define XIN_CIE_OFFSET 5 /* Clear Interrupt Enable Register */ -#define XIN_IVR_OFFSET 6 /* Interrupt Vector Register */ -#define XIN_MER_OFFSET 7 /* Master Enable Register */ -#define XIN_IMR_OFFSET 8 /* Interrupt Mode Register , this is present - * only for Fast Interrupt */ -#define XIN_IVAR_OFFSET 64 /* Interrupt Vector Address Register - * Interrupt 0 Offest, this is present - * only for Fast Interrupt */ - -#else /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */ - -#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */ -#define XIN_IPR_OFFSET 4 /* Interrupt Pending Register */ -#define XIN_IER_OFFSET 8 /* Interrupt Enable Register */ -#define XIN_IAR_OFFSET 12 /* Interrupt Acknowledge Register */ -#define XIN_SIE_OFFSET 16 /* Set Interrupt Enable Register */ -#define XIN_CIE_OFFSET 20 /* Clear Interrupt Enable Register */ -#define XIN_IVR_OFFSET 24 /* Interrupt Vector Register */ -#define XIN_MER_OFFSET 28 /* Master Enable Register */ -#define XIN_IMR_OFFSET 32 /* Interrupt Mode Register , this is present - * only for Fast Interrupt */ -#define XIN_ILR_OFFSET 36 /* Interrupt level register */ -#define XIN_IVAR_OFFSET 0x100 /* Interrupt Vector Address Register - * Interrupt 0 Offest, this is present - * only for Fast Interrupt */ - - - -#endif /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */ - -/* Bit definitions for the bits of the MER register */ - -#define XIN_INT_MASTER_ENABLE_MASK 0x1UL -#define XIN_INT_HARDWARE_ENABLE_MASK 0x2UL /* once set cannot be cleared */ - -/**************************** Type Definitions *******************************/ - -/* The following data type defines each entry in an interrupt vector table. - * The callback reference is the base address of the interrupting device - * for the driver interface given in this file and an instance pointer for the - * driver interface given in xintc.h file. - */ -typedef struct { - XInterruptHandler Handler; - void *CallBackRef; -} XIntc_VectorTableEntry; - -typedef void (*XFastInterruptHandler) (void); - -/***************** Macros (Inline Functions) Definitions *********************/ - -/* - * Define the appropriate I/O access method to memory mapped I/O or DCR. - */ -#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) - -#define XIntc_In32 XIo_DcrIn -#define XIntc_Out32 XIo_DcrOut - -#else - -#define XIntc_In32 Xil_In32 -#define XIntc_Out32 Xil_Out32 - -#endif - -/****************************************************************************/ -/** -* -* Enable all interrupts in the Master Enable register of the interrupt -* controller. The interrupt controller defaults to all interrupts disabled -* from reset such that this macro must be used to enable interrupts. -* -* @param BaseAddress is the base address of the device. -* -* @return None. -* -* @note C-style signature: -* void XIntc_MasterEnable(u32 BaseAddress); -* -*****************************************************************************/ -#define XIntc_MasterEnable(BaseAddress) \ - XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, \ - XIN_INT_MASTER_ENABLE_MASK | XIN_INT_HARDWARE_ENABLE_MASK) - -/****************************************************************************/ -/** -* -* Disable all interrupts in the Master Enable register of the interrupt -* controller. -* -* @param BaseAddress is the base address of the device. -* -* @return None. -* -* @note C-style signature: -* void XIntc_MasterDisable(u32 BaseAddress); -* -*****************************************************************************/ -#define XIntc_MasterDisable(BaseAddress) \ - XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, 0) - -/****************************************************************************/ -/** -* -* Enable specific interrupt(s) in the interrupt controller. -* -* @param BaseAddress is the base address of the device -* @param EnableMask is the 32-bit value to write to the enable register. -* Each bit of the mask corresponds to an interrupt input signal -* that is connected to the interrupt controller (INT0 = LSB). -* Only the bits which are set in the mask will enable interrupts. -* -* @return None. -* -* @note C-style signature: -* void XIntc_EnableIntr(u32 BaseAddress, u32 EnableMask); -* -*****************************************************************************/ -#define XIntc_EnableIntr(BaseAddress, EnableMask) \ - XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, (EnableMask)) - -/****************************************************************************/ -/** -* -* Disable specific interrupt(s) in the interrupt controller. -* -* @param BaseAddress is the base address of the device -* @param DisableMask is the 32-bit value to write to the enable register. -* Each bit of the mask corresponds to an interrupt input signal -* that is connected to the interrupt controller (INT0 = LSB). -* Only the bits which are set in the mask will disable interrupts. -* -* @return None. -* -* @note C-style signature: -* void XIntc_DisableIntr(u32 BaseAddress, u32 DisableMask); -* -*****************************************************************************/ -#define XIntc_DisableIntr(BaseAddress, DisableMask) \ - XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, ~(DisableMask)) - -/****************************************************************************/ -/** -* -* Acknowledge specific interrupt(s) in the interrupt controller. -* -* @param BaseAddress is the base address of the device -* @param AckMask is the 32-bit value to write to the acknowledge -* register. Each bit of the mask corresponds to an interrupt input -* signal that is connected to the interrupt controller (INT0 = -* LSB). Only the bits which are set in the mask will acknowledge -* interrupts. -* -* @return None. -* -* @note C-style signature: -* void XIntc_AckIntr(u32 BaseAddress, u32 AckMask); -* -*****************************************************************************/ -#define XIntc_AckIntr(BaseAddress, AckMask) \ - XIntc_Out32((BaseAddress) + XIN_IAR_OFFSET, (AckMask)) - -/****************************************************************************/ -/** -* -* Get the interrupt status from the interrupt controller which indicates -* which interrupts are active and enabled. -* -* @param BaseAddress is the base address of the device -* -* @return The 32-bit contents of the interrupt status register. Each bit -* corresponds to an interrupt input signal that is connected to -* the interrupt controller (INT0 = LSB). Bits which are set -* indicate an active interrupt which is also enabled. -* -* @note C-style signature: -* u32 XIntc_GetIntrStatus(u32 BaseAddress); -* -*****************************************************************************/ -#define XIntc_GetIntrStatus(BaseAddress) \ - (XIntc_In32((BaseAddress) + XIN_ISR_OFFSET) & \ - XIntc_In32((BaseAddress) + XIN_IER_OFFSET)) - -/************************** Function Prototypes ******************************/ - -/* - * Interrupt controller handlers, to be connected to processor exception - * handling code. - */ -void XIntc_LowLevelInterruptHandler(void); -void XIntc_DeviceInterruptHandler(void *DeviceId); - -/* Various configuration functions */ -void XIntc_SetIntrSvcOption(u32 BaseAddress, int Option); - -void XIntc_RegisterHandler(u32 BaseAddress, int InterruptId, - XInterruptHandler Handler, void *CallBackRef); - -void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id, - XFastInterruptHandler FastHandler); - -/************************** Variable Definitions *****************************/ - - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xllfifo.h b/thirdparty/libxil/include/xilinx/xllfifo.h deleted file mode 100644 index e9b59d77c..000000000 --- a/thirdparty/libxil/include/xilinx/xllfifo.h +++ /dev/null @@ -1,715 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** - * - * @file xllfifo.h -* @addtogroup llfifo_v5_0 -* @{ -* @details - * - * The Xilinx Dual Channel Fifo driver component. This driver supports the - * Virtex-5(TM) and Virtex-4(TM) XPS_ll_Fifo and the AxiFifo. - * - * For a full description of the bridge features, please see the HW spec. This - * driver supports the following features: - * - Memory mapped access to host interface registers - * - API for polled frame transfers - * - API for interrupt driven frame transfers - * - Virtual memory support - * - Full duplex operation - * - *

Driver Description

- * - * This driver enables higher layer software to access the XPS_llFifo core - * using any alignment in the data buffers. - * - * This driver supports send and receive channels in the same instance - * structure in the same fashion as the hardware core. - * - *

Initialization

- * - * An instance of this driver is initialized using a call to Initialize(). - * - *

Usage

- * - * It is fairly simple to use the API provided by this FIFO driver. The - * only somewhat tricky part is that the calling code must correctly call - * a couple routines in the right sequence for receive and transmit. - * - * This sequence is described here. Check the routine functional - * descriptions for information on how to use a specific API routine. - * - *

Receive

- * - * A frame is received by using the following sequence:
- * 1) call XLlFifo_RxOccupancy() to check the occupancy count
- * 2) call XLlFifo_RxGetLen() to get the length of the next incoming frame
- * 3) call XLlFifo_Read() one or more times to read the number of bytes - * reported by XLlFifo_RxGetLen().
- * - * For example: - *
- * 	while (XLlFifo_RxOccupancy(&RxInstance)) {
- * 		frame_len = XLlFifo_RxGetLen(&RxInstance);
- *		while (frame_len) {
- * 			unsigned bytes = min(sizeof(buffer), frame_len);
- * 			XLlFifo_Read(&RxInstance, buffer, bytes);
- * 			// ********
- * 			// do something with buffer here
- * 			// ********
- * 			frame_len -= bytes;
- *		}
- * 	}
- * 
- * - * This FIFO hardware core does not support a sequence where the - * calling code calls RxGetLen() twice in a row and then receive the data - * for two frames. Each frame must be read in by calling RxGetLen() just - * prior to reading the data. - * - *

Transmit

- * A frame is transmittted by using the following sequence:
- * 1) call XLlFifo_Write() one or more times to write all the of bytes in - * the next frame.
- * 2) call XLlFifo_TxSetLen() to begin the transmission of frame just - * written.
- * - * For example: - *
- * 	frame_left = frame_len;
- * 	while (frame_left) {
- * 		unsigned bytes = min(sizeof(buffer), frame_left);
- * 		XLlFifo_Write(&TxInstance, buffer, bytes);
- * 		// ********
- * 		// do something here to refill buffer
- * 		// ********
- * 		frame_left -= bytes;
- * 	}
- * 	XLlFifo_TxSetLen(&RxInstance, frame_len);
- * 
- * - * This FIFO hardware core does not support a sequence where the - * calling code writes the data for two frames and then calls TxSetLen() - * twice in a row. Each frame must be written by writting the data for one - * frame and then calling TxSetLen(). - * - *

Interrupts

- * This driver does not handle interrupts from the FIFO hardware. The - * software layer above may make use of the interrupts by setting up its - * own handlers for the interrupts. - * - *
- * MODIFICATION HISTORY:
- *
- * Ver   Who  Date     Changes
- * ----- ---- -------- -------------------------------------------------------
- * 1.00a jvb  10/12/06 First release
- * 1.01a sdm  08/22/08 Removed support for static interrupt handlers from the
- *		       MDD file
- * 1.02a jz   12/04/09 Hal phase 1 support
- * 2.01a asa  09/17/10 Added code for resetting Local Link/AXI Streaming
- *		       interface for CR574868
- * 2.02a asa  12/27/11 Changed the function XStrm_Read in xtreamer.c to reset
- *		       HeadIndex to zero when all bytes have been read.
- *		       Changed the macro XStrm_IsRxInternalEmpty in file
- *		       xtreamer.h to use FrmByteCnt instead of HeadIndex.
- *		       When FrmByteCnt is zero, this means all internal buffers
- *		       in streamer are empty. Earlier implementation using
- *		       HeadIndex was not very clear and could give improper
- *		       results for some cases.
- *		       Changed the macro XLlFifo_IsRxEmpty in file xllfifo.h
- *		       These changes are done to fix the CR 604650.
-  * 2.03a asa  14/08/12  Added XLLF_TDR_OFFSET, XLLF_RDR_OFFSET
- *		         defines for the new registers, and XLLF_INT_TFPF_MASK,
- *		         XLLF_INT_TFPE_MASK, XLLF_INT_RFPF_MASK and
- *		         XLLF_INT_RFPE_MASK for the new version of the
- *		         AXI4-Stream FIFO core (v2.01a and later)
- *
- * 3.00a adk 08/10/13 Added support for AXI4 Datainterface.Changes are
- * 		      In Xllfifo.c file XLlFifo_RxGetWord,XLlFifo_TxPutword.
- * 		      In XLlfifo.h file updated XLlfifo structure for
- * 		      Axi4BaseAddress and for Datainterface type provided
- *		      polling and interrupt examples. XLlfifo_IsRxDone Macro
- *		      Is added in the XLlfifo.h file for polledmode exmaple.
- *		      Added Static initialzation for the driver.
- *		      XLlFifo_Initialize is still used to make the driver
- *		      backward compatible.
- * 4.0   adk  19/12/13 Updated as per the New Tcl API's
- * 5.0   adk  15/05/15 Updated the register offsets in the AXI4 data path
- *		       as per latest IP version(v4.1)(CR:860254).
- *
- * 
- * - *****************************************************************************/ -#ifndef XLLFIFO_H /* prevent circular inclusions */ -#define XLLFIFO_H /* by using preprocessor symbols */ - -/* force C linkage */ -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -/* This order needs to be kept this way to avoid xstatus/xil_types conflict */ -#include "xstreamer.h" -#include "xllfifo_hw.h" - -/**************************** Type Definitions *******************************/ - -/** - * This typedef defines a run-time instance of an XLlFifo device. - */ -typedef struct XLlFifo { - u32 BaseAddress; /**< BaseAddress is the physical base address of the - * device's registers - */ - - u32 IsReady; /**< IsReady is non-zero if the driver instance - * has been initialized. - */ - - u32 Axi4BaseAddress; /**< BaseAddress if the FIFO Data interface is - * AXI4 this address should use for FIFO - * access - */ - u32 Datainterface; /**< Data interface of the FIFO. This value is zero - * if the Datainterface is AXI4-lite. - */ - XStrm_RxFifoStreamer RxStreamer; /**< RxStreamer is the byte streamer - * instance for the receive channel. - */ - XStrm_TxFifoStreamer TxStreamer; /**< TxStreamer is the byte streamer - * instance for the transmit channel. - */ -} XLlFifo; - -typedef struct XLlFifo_Config { - u32 DeviceId; /**< Deviceid of the AXI FIFO */ - u32 BaseAddress; /**< Base Address of the AXI FIFO */ - u32 Axi4BaseAddress; /**< Axi4 interface Base address */ - u32 Datainterface; /**< Type of Datainterface */ -}XLlFifo_Config; - -/****************************************************************************/ -/** -* -* XLlFifo_Reset resets both the Tx and Rx channels and the local link interface -* the FIFO specified by InstancePtr. XLlFifo_TxReset resets also sends a -* reset pulse to the downstream device (e.g. TEMAC). XLlFifo_Reset drops any -* bytes in the FIFO not yet retrieved. XLlFifo_Reset drops any bytes in the FIFO -* not yet transmitted. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_Reset(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_Reset(InstancePtr) \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, \ - XLLF_LLR_RESET_MASK) - - -/****************************************************************************/ -/** -* -* XLlFifo_Status returns a bit mask of the interrupt status register (ISR) -* for the FIFO specified by InstancePtr. XLlFifo_Status can be used -* to query the status of the FIFO without having to have interrupts enabled. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_IntStatus returns a bit mask of the status conditions. -* The mask will be a set of bitwise or'd values from the -* XLLF_INT_*_MASK preprocessor symbols. -* -* @note -* C-style signature: -* u32 XLlFifo_IntStatus(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_Status(InstancePtr) \ - XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) - -/****************************************************************************/ -/** -* -* XLlFifo_IntEnable enables the interrupts specified in Mask for the -* FIFO specified by InstancePtr. The corresponding interrupt for each bit -* set to 1 in Mask, will be enabled. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param Mask contains a bit mask of the interrupts to enable. The mask -* can be formed using a set of bitwise or'd values from the -* XLLF_INT_*_MASK preprocessor symbols. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_IntEnable(XLlFifo *InstancePtr, u32 Mask) -* -*****************************************************************************/ -#define XLlFifo_IntEnable(InstancePtr, Mask) \ -{ \ - u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \ - XLLF_IER_OFFSET); \ - Reg |= ((Mask) & XLLF_INT_ALL_MASK); \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \ - Reg); \ -} - -/****************************************************************************/ -/** -* -* XLlFifo_IntDisable disables the interrupts specified in Mask for the -* FIFO specified by InstancePtr. The corresponding interrupt for each bit -* set to 1 in Mask, will be disabled. In other words, XLlFifo_IntDisable -* uses the "set a bit to clear it" scheme. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param Mask contains a bit mask of the interrupts to disable. The mask -* can be formed using a set of bitwise or'd values from the -* XLLF_INT_*_MASK preprocessor symbols. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_IntDisable(XLlFifo *InstancePtr, u32 Mask) -* -*****************************************************************************/ -#define XLlFifo_IntDisable(InstancePtr, Mask) \ -{ \ - u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \ - XLLF_IER_OFFSET); \ - Reg &= ~((Mask) & XLLF_INT_ALL_MASK); \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \ - Reg); \ -} - -/****************************************************************************/ -/** -* -* XLlFifo_IntPending returns a bit mask of the pending interrupts for the -* FIFO specified by InstancePtr. Each bit set to 1 in the return value -* represents a pending interrupt. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_IntPending returns a bit mask of the interrupts that are -* pending. The mask will be a set of bitwise or'd values from the -* XLLF_INT_*_MASK preprocessor symbols. -* -* @note -* C-style signature: -* u32 XLlFifo_IntPending(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#ifdef DEBUG -extern u32 _xllfifo_ipie_value; -extern u32 _xllfifo_ipis_value; -#define XLlFifo_IntPending(InstancePtr) \ - (_xllfifo_ipie_value = XLlFifo_ReadReg( \ - (InstancePtr)->BaseAddress, XLLF_IER_OFFSET), \ - _xllfifo_ipis_value = XLlFifo_ReadReg( \ - (InstancePtr)->BaseAddress, XLLF_ISR_OFFSET), \ - (_xllfifo_ipie_value & _xllfifo_ipis_value)) -#else -#define XLlFifo_IntPending(InstancePtr) \ - (XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET) & \ - XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET)) -#endif - -/****************************************************************************/ -/** -* -* XLlFifo_IntClear clears pending interrupts specified in Mask for the -* FIFO specified by InstancePtr. The corresponding pending interrupt for -* each bit set to 1 in Mask, will be cleared. In other words, -* XLlFifo_IntClear uses the "set a bit to clear it" scheme. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param Mask contains a bit mask of the pending interrupts to clear. The -* mask can be formed using a set of bitwise or'd values from the -* XLLF_INT_*_MASK preprocessor symbols. -* -* @note -* C-style signature: -* void XLlFifo_IntClear(XLlFifo *InstancePtr, u32 Mask) -* -*****************************************************************************/ -#define XLlFifo_IntClear(InstancePtr, Mask) \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET, \ - ((Mask) & XLLF_INT_ALL_MASK)) - -/****************************************************************************/ -/** -* -* XLlFifo_RxReset resets the receive channel of the FIFO specified by -* InstancePtr. XLlFifo_RxReset drops any bytes in the FIFO not yet -* retrieved. -* -* The calling software may want to test for the completion of the reset by -* reading the interrupt status (IS) register and testing for the Rx Reset -* complete (RRC) bit. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_RxReset(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_RxReset(InstancePtr) \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_RDFR_OFFSET, \ - XLLF_RDFR_RESET_MASK) - -/****************************************************************************/ -/** -* -* XLlFifo_IsRxEmpty returns true if the receive channel of the FIFO, specified -* by InstancePtr, is empty. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_IsRxEmpty returns TRUE when the receive channel of the -* FIFO is empty. Otherwise, XLlFifo_IsRxEmpty returns FALSE. -* -* @note -* C-style signature: -* int XLlFifo_IsRxEmpty(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_IsRxEmpty(InstancePtr) \ - ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDFO_OFFSET) == 0) \ - ? TRUE : FALSE) - - -/*****************************************************************************/ -/** -* -* XLlFifo_RxOccupancy returns the number of 32-bit words available (occupancy) to -* be read from the receive channel of the FIFO, specified by InstancePtr. -* -* The xps_ll_fifo core uses the same fifo to store data values and frame length -* values. Upon initialization, the XLlFifo_RxOccupancy will give the value of -* 1, which means one length value (a reserved fifo location) and no data -* values. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_RxOccupancy returns the occupancy count for the specified -* packet FIFO. -* -* @note -* -* C Signature: u32 XLlFifo_RxOccupancy(XLlFifo *InstancePtr) -* -******************************************************************************/ -#define XLlFifo_RxOccupancy(InstancePtr) \ - XStrm_RxOccupancy(&((InstancePtr)->RxStreamer)) - -/*****************************************************************************/ -/** -* -* XLlFifo_RxGetLen notifies the hardware that the program is ready to receive -* the next frame from the receive channel of the FIFO, specified by -* InstancePtr. -* -* Note that the program must first call XLlFifo_RxGetLen before pulling data -* out of the receive channel of the FIFO with XLlFifo_Read. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_RxGetLen returns the number of bytes available in the next -* frame. -* -* @note -* -* C Signature: u32 XLlFifo_RxGetLen(XLlFifo *InstancePtr) -* -******************************************************************************/ -#define XLlFifo_RxGetLen(InstancePtr) \ - XStrm_RxGetLen(&((InstancePtr)->RxStreamer)) - -/*****************************************************************************/ -/** -* -* XLlFifo_Read reads Bytes bytes from the receive channel of the FIFO -* referenced by InstancePtr to the block of memory, referenced by -* BufPtr. -* -* Care must be taken to ensure that the number of bytes read with one or more -* calls to XLlFifo_Read() does not exceed the number of bytes available given -* from the last call to XLlFifo_RxGetLen(). -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param BufPtr specifies the memory address to place the data read. -* -* @param Bytes specifies the number of bytes to read. -* -* @return N/A -* -* @note -* Error handling is handled through hardware exceptions and interrupts. -* -* C Signature: void XLlFifo_Read(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes) -* -******************************************************************************/ -#define XLlFifo_Read(InstancePtr, BufPtr, Bytes) \ - XStrm_Read(&((InstancePtr)->RxStreamer), (BufPtr), (Bytes)) - -/****************************************************************************/ -/** -* -* XLlFifo_TxReset resets the transmit channel of the FIFO specified by -* InstancePtr. XLlFifo_TxReset drops any bytes in the FIFO not yet -* transmitted. -* -* The calling software may want to test for the completion of the reset by -* reading the interrupt status (IS) register and testing for the Tx Reset -* complete (TRC) bit. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_TxReset(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_TxReset(InstancePtr) \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFR_OFFSET, \ - XLLF_TDFR_RESET_MASK) - -/****************************************************************************/ -/** -* -* XLlFifo_IsTxDone returns true if the transmission in the transmit channel -* of the FIFO, specified by InstancePtr, is complete. XLlFifo_IsTxDone -* works only if the TC bit in the IS register is cleared before sending a -* frame. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_IsTxDone returns TRUE when the transmit channel of the -* FIFO is complete. Otherwise, XLlFifo_IsTxDone returns FALSE. -* -* @note -* C-style signature: -* int XLlFifo_IsTxDone(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_IsTxDone(InstancePtr) \ - ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \ - XLLF_INT_TC_MASK) \ - ? TRUE : FALSE) - -/****************************************************************************/ -/** -* -* XLlFifo_IsRxDone returns true if the reception in the receive channel -* of the FIFO, specified by InstancePtr, is complete. XLlFifo_IsRxDone -* works only if the RC bit in the ISR register is cleared before receiving a -* frame. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_IsRxDone returns TRUE when the receive channel of the -* FIFO is complete. Otherwise, XLlFifo_IsRxDone returns FALSE. -* -* @note -* C-style signature: -* int XLlFifo_IsRxDone(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_IsRxDone(InstancePtr) \ - ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \ - XLLF_INT_RC_MASK) \ - ? TRUE : FALSE) - -/****************************************************************************/ -/** -* -* XLlFifo_TxVacancy returns the number of unused 32 bit words available -* (vacancy) in the send channel of the FIFO specified by InstancePtr. -* -* The xps_ll_fifo core uses the same fifo to store data values and frame length -* values. Upon initialization, the XLlFifo_TxVacancy will give the value of -* FIFO_WIDTH - 1, which means one length value used (a reserved fifo location) -* and no data values yet present. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return XLlFifo_TxVacancy returns the vacancy count in 32-bit words for -* the specified FIFO. -* -* @note -* C-style signature: -* u32 XLlFifo_TxVacancy(XLlFifo *InstancePtr) -* -*****************************************************************************/ -#define XLlFifo_TxVacancy(InstancePtr) \ - XStrm_TxVacancy(&((InstancePtr)->TxStreamer)) - -/*****************************************************************************/ -/** -* -* XLlFifo_TxSetLen begins a hardware transfer of Bytes bytes out of the -* transmit channel of the FIFO specified by InstancePtr. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param Bytes specifies the frame length in bytes. -* -* @return N/A -* -* @note -* -* C Signature: void XLlFifo_TxSetLen(XLlFifo *InstancePtr, u32 Bytes) -* -******************************************************************************/ -#define XLlFifo_TxSetLen(InstancePtr, Bytes) \ - XStrm_TxSetLen(&((InstancePtr)->TxStreamer), (Bytes)) - -/*****************************************************************************/ -/** -* -* XLlFifo_Write writes Bytes bytes of the block of memory, referenced by -* BufPtr, to the transmit channel of the FIFO referenced by -* InstancePtr. -* -* Care must be taken to ensure that the number of bytes written with one or -* more calls to XLlFifo_Write() matches the number of bytes given in the next -* call to XLlFifo_TxSetLen(). -* -* @param InstancePtr references the FIFO on which to operate. -* -* @param BufPtr specifies the memory address of data to write. -* -* @param Bytes specifies the number of bytes to write. -* -* @return N/A -* -* @note -* Error handling is handled through hardware exceptions and interrupts. -* -* C Signature: void XLlFifo_Write(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes) -* -******************************************************************************/ -#define XLlFifo_Write(InstancePtr, BufPtr, Bytes) \ - XStrm_Write(&((InstancePtr)->TxStreamer), (BufPtr), (Bytes)) - - -/*****************************************************************************/ -/** -* -* XLlFifo_WriteTdr writes to the Transmit Destination Register (TDR) -* -* The TDR stores the destination address corresponding to the packet to be -* transmitted. When presenting a transmit packet to the AXI4-Stream FIFO core -* the following sequence should be followed -* - Write the destination address into TDR first, -* - Write the packet data to the Transmit Data FIFO next -* - Write the length of the packet into the Transmit Length Register. -* -* @param InstancePtr references the FIFO on which to operate. -* @param Tdest is the Transmit Destination address to be written to TDR. -* -* @return N/A -* -* @note C Signature: -* void XLlFifo_WriteTdr(XLlFifo *InstancePtr, u32 Tdest); -* -******************************************************************************/ -#define XLlFifo_WriteTdr(InstancePtr, Tdest) \ - XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDR_OFFSET, \ - Tdest & 0xF) - -/*****************************************************************************/ -/** -* -* XLlFifo_ReadTdr returns the contents of the Receive Destination Register(RDR). -* -* The RDR contains destination address corresponding to the valid packet that -* is received. The RDR should only be read when a receive packet is available -* for processing (the receive occupancy is not zero). -* Once the RDR is read, the receive packet data should be read from the receive -* data FIFO before the RDR is read again. The RDR values are stored in the -* receive data FIFO by the AXI4-Stream FIFO core with the data of each packet. -* The RDR value for the subsequent packet to be processed is moved to the RDR -* when the previous RDR value has been read. -* -* @param InstancePtr references the FIFO on which to operate. -* -* @return The Receive Destination address read from the RDR. -* -* @note C Signature: -* u32 XLlFifo_ReadRdr(XLlFifo *InstancePtr) -* -******************************************************************************/ -#define XLlFifo_ReadRdr(InstancePtr) \ - XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDR_OFFSET) - -/************************** Function Prototypes ******************************/ -/* - * Initialization functions xllfifo.c - */ -int XLlFifo_CfgInitialize(XLlFifo *InstancePtr, - XLlFifo_Config *Config, u32 EffectiveAddress); -void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress); -XLlFifo_Config *XLlFfio_LookupConfig(u32 DeviceId); -u32 XLlFifo_iRxOccupancy(XLlFifo *InstancePtr); -u32 XLlFifo_iRxGetLen(XLlFifo *InstancePtr); -u32 XLlFifo_iTxVacancy(XLlFifo *InstancePtr); -void XLlFifo_iTxSetLen(XLlFifo *InstancePtr, u32 Bytes); -u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr); -void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word); - -#ifdef __cplusplus -} -#endif -#endif /* XLLFIFO_H end of preprocessor protection symbols */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xllfifo_hw.h b/thirdparty/libxil/include/xilinx/xllfifo_hw.h deleted file mode 100644 index 694dd358e..000000000 --- a/thirdparty/libxil/include/xilinx/xllfifo_hw.h +++ /dev/null @@ -1,242 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xllfifo_hw.h -* @addtogroup llfifo_v5_0 -* @{ -* -* This header file contains identifiers and low-level driver functions (or -* macros) that can be used to access the xps_ll_fifo core. -* High-level driver functions are defined in xpfifo.h. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a jvb  10/16/06 First release.
-* 1.02a jz   12/04/09  Hal phase 1 support
-* 2.00a hbm  01/20/10  Hal phase 1 support, bump up major release
-* 2.03a asa  14/08/12  Added XLLF_TDR_OFFSET, XLLF_RDR_OFFSET
-*		       defines for the new registers, and XLLF_INT_TFPF_MASK,
-*		       XLLF_INT_TFPE_MASK, XLLF_INT_RFPF_MASK and
-*		       XLLF_INT_RFPE_MASK for the new version of the
-*		       AXI4-Stream FIFO core (v2.01a and later)
-* 
-* -******************************************************************************/ - -#ifndef XLLFIFO_HW_H /* prevent circular inclusions */ -#define XLLFIFO_HW_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xdebug.h" -#include "xil_io.h" -#include "xil_types.h" - -/************************** Constant Definitions *****************************/ - -/* Register offset definitions. Unless otherwise noted, register access is - * 32 bit. - */ - -/** @name Registers - * @{ - */ -#define XLLF_ISR_OFFSET 0x00000000 /**< Interrupt Status */ -#define XLLF_IER_OFFSET 0x00000004 /**< Interrupt Enable */ - -#define XLLF_TDFR_OFFSET 0x00000008 /**< Transmit Reset */ -#define XLLF_TDFV_OFFSET 0x0000000c /**< Transmit Vacancy */ -#define XLLF_TDFD_OFFSET 0x00000010 /**< Transmit Data */ -#define XLLF_AXI4_TDFD_OFFSET 0x00000000 /**< Axi4 Transmit Data */ -#define XLLF_TLF_OFFSET 0x00000014 /**< Transmit Length */ - -#define XLLF_RDFR_OFFSET 0x00000018 /**< Receive Reset */ -#define XLLF_RDFO_OFFSET 0x0000001c /**< Receive Occupancy */ -#define XLLF_RDFD_OFFSET 0x00000020 /**< Receive Data */ -#define XLLF_AXI4_RDFD_OFFSET 0x00001000 /**< Axi4 Receive Data */ -#define XLLF_RLF_OFFSET 0x00000024 /**< Receive Length */ -#define XLLF_LLR_OFFSET 0x00000028 /**< Local Link Reset */ -#define XLLF_TDR_OFFSET 0x0000002C /**< Transmit Destination */ -#define XLLF_RDR_OFFSET 0x00000030 /**< Receive Destination */ - -/*@}*/ - -/* Register masks. The following constants define bit locations of various - * control bits in the registers. Constants are not defined for those registers - * that have a single bit field representing all 32 bits. For further - * information on the meaning of the various bit masks, refer to the HW spec. - */ - -/** @name Interrupt bits - * These bits are associated with the XLLF_IER_OFFSET and XLLF_ISR_OFFSET - * registers. - * @{ - */ -#define XLLF_INT_RPURE_MASK 0x80000000 /**< Receive under-read */ -#define XLLF_INT_RPORE_MASK 0x40000000 /**< Receive over-read */ -#define XLLF_INT_RPUE_MASK 0x20000000 /**< Receive underrun (empty) */ -#define XLLF_INT_TPOE_MASK 0x10000000 /**< Transmit overrun */ -#define XLLF_INT_TC_MASK 0x08000000 /**< Transmit complete */ -#define XLLF_INT_RC_MASK 0x04000000 /**< Receive complete */ -#define XLLF_INT_TSE_MASK 0x02000000 /**< Transmit length mismatch */ -#define XLLF_INT_TRC_MASK 0x01000000 /**< Transmit reset complete */ -#define XLLF_INT_RRC_MASK 0x00800000 /**< Receive reset complete */ -#define XLLF_INT_TFPF_MASK 0x00400000 /**< Tx FIFO Programmable Full, - * AXI FIFO MM2S Only */ -#define XLLF_INT_TFPE_MASK 0x00200000 /**< Tx FIFO Programmable Empty - * AXI FIFO MM2S Only */ -#define XLLF_INT_RFPF_MASK 0x00100000 /**< Rx FIFO Programmable Full - * AXI FIFO MM2S Only */ -#define XLLF_INT_RFPE_MASK 0x00080000 /**< Rx FIFO Programmable Empty - * AXI FIFO MM2S Only */ -#define XLLF_INT_ALL_MASK 0xfff80000 /**< All the ints */ -#define XLLF_INT_ERROR_MASK 0xf2000000 /**< Error status ints */ -#define XLLF_INT_RXERROR_MASK 0xe0000000 /**< Receive Error status ints */ -#define XLLF_INT_TXERROR_MASK 0x12000000 /**< Transmit Error status ints */ -/*@}*/ - -/** @name Reset register values - * These bits are associated with the XLLF_TDFR_OFFSET and XLLF_RDFR_OFFSET - * reset registers. - * @{ - */ -#define XLLF_RDFR_RESET_MASK 0x000000a5 /**< receive reset value */ -#define XLLF_TDFR_RESET_MASK 0x000000a5 /**< Transmit reset value */ -#define XLLF_LLR_RESET_MASK 0x000000a5 /**< Local Link reset value */ -/*@}*/ - -/**************************** Type Definitions *******************************/ - -/***************** Macros (Inline Functions) Definitions *********************/ - -/**** debug macros ****/ -#define XLlFifo_reg_name(RegOffset) \ - (((RegOffset) == XLLF_ISR_OFFSET) ? "ISR": \ - ((RegOffset) == XLLF_IER_OFFSET) ? "IER": \ - ((RegOffset) == XLLF_TDFR_OFFSET) ? "TDFR {tx reset}": \ - ((RegOffset) == XLLF_TDFV_OFFSET) ? "TDFV {tx vacancy}": \ - ((RegOffset) == XLLF_TDFD_OFFSET) ? "TDFD {tx data}": \ - ((RegOffset) == XLLF_TLF_OFFSET) ? "TLF {tx length}": \ - ((RegOffset) == XLLF_RDFR_OFFSET) ? "RDFR {rx reset}": \ - ((RegOffset) == XLLF_RDFO_OFFSET) ? "RDFO {rx occupancy}": \ - ((RegOffset) == XLLF_RDFD_OFFSET) ? "RDFD {rx data}": \ - ((RegOffset) == XLLF_RLF_OFFSET) ? "RLF {rx length}": \ - "unknown") - -#define XLlFifo_print_reg_o(BaseAddress, RegOffset, Value) \ - xdbg_printf(XDBG_DEBUG_FIFO_REG, "0x%08x -> %s(0x%08x)\n", (Value), \ - XLlFifo_reg_name(RegOffset), \ - (RegOffset) + (BaseAddress)) - -#define XLlFifo_print_reg_i(BaseAddress, RegOffset, Value) \ - xdbg_printf(XDBG_DEBUG_FIFO_REG, "%s(0x%08x) -> 0x%08x\n", \ - XLlFifo_reg_name(RegOffset), \ - (RegOffset) + (BaseAddress), (Value)) -/**** end debug macros ****/ - -/****************************************************************************/ -/** -* -* XLlFifo_ReadReg returns the value of the register at the offet, -* RegOffset, from the memory mapped base address, BaseAddress. -* -* @param BaseAddress specifies the base address of the device. -* -* @param RegOffset specifies the offset from BaseAddress. -* -* @return XLlFifo_ReadReg returns the value of the specified register. -* -* @note -* C-style signature: -* u32 XLlFifo_ReadReg(u32 BaseAddress, u32 RegOffset) -* -*****************************************************************************/ -#ifdef DEBUG -extern u32 _xllfifo_rr_value; -#define XLlFifo_ReadReg(BaseAddress, RegOffset) \ - ((((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \ - "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \ - (RegOffset)) : 0), \ - _xllfifo_rr_value = Xil_In32((BaseAddress) + (RegOffset)), \ - XLlFifo_print_reg_i((BaseAddress), (RegOffset), _xllfifo_rr_value), \ - _xllfifo_rr_value) -#else -#define XLlFifo_ReadReg(BaseAddress, RegOffset) \ - (Xil_In32((BaseAddress) + (RegOffset))) -#endif - -/****************************************************************************/ -/** -* -* XLlFifo_WriteReg writes the value, Value, to the register at the -* offet, RegOffset, from the memory mapped base address, -* BaseAddress. -* -* @param BaseAddress specifies the base address of the device. -* -* @param RegOffset specifies the offset from BaseAddress. -* -* @param Value is value to write to the register. -* -* @return N/A -* -* @note -* C-style signature: -* void XLlFifo_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Value) -* -*****************************************************************************/ -#ifdef DEBUG -#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \ - (((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \ - "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \ - (RegOffset)) : 0), \ - XLlFifo_print_reg_o((BaseAddress), (RegOffset), (Value)), \ - (Xil_Out32((BaseAddress) + (RegOffset), (Value))) -#else -#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \ - ((Xil_Out32((BaseAddress) + (RegOffset), (Value)))) -#endif - -#ifdef __cplusplus -} -#endif -#endif /* XLLFIFO_HW_H end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xparameters.h b/thirdparty/libxil/include/xilinx/xparameters.h deleted file mode 100644 index 279ab6a47..000000000 --- a/thirdparty/libxil/include/xilinx/xparameters.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _X_PARAMETERS_H_ -#define _X_PARAMETERS_H_ - -/* We set all instance counters to zero - * to avoid the generation of configuration tables - * See: *_g.c, *_sinit.c source files - */ -#define XPAR_XLLFIFO_NUM_INSTANCES 0 -#define XPAR_XTMRCTR_NUM_INSTANCES 0 -#define XPAR_XAXIDMA_NUM_INSTANCES 0 -#define XPAR_XAXIS_SWITCH_NUM_INSTANCES 0 - -#define XPAR_XINTC_NUM_INSTANCES 0 -#define XPAR_INTC_MAX_NUM_INTR_INPUTS 0 - -#endif \ No newline at end of file diff --git a/thirdparty/libxil/include/xilinx/xstatus.h b/thirdparty/libxil/include/xilinx/xstatus.h deleted file mode 100644 index a8caf2f4e..000000000 --- a/thirdparty/libxil/include/xilinx/xstatus.h +++ /dev/null @@ -1,432 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xstatus.h -* @addtogroup common_v1_00_a -* @{ -* -* This file contains Xilinx software status codes. Status codes have their -* own data type called int. These codes are used throughout the Xilinx -* device drivers. -* -******************************************************************************/ - -#ifndef XSTATUS_H /* prevent circular inclusions */ -#define XSTATUS_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xbasic_types.h" - -/************************** Constant Definitions *****************************/ - -/*********************** Common statuses 0 - 500 *****************************/ - -#define XST_SUCCESS 0L -#define XST_FAILURE 1L -#define XST_DEVICE_NOT_FOUND 2L -#define XST_DEVICE_BLOCK_NOT_FOUND 3L -#define XST_INVALID_VERSION 4L -#define XST_DEVICE_IS_STARTED 5L -#define XST_DEVICE_IS_STOPPED 6L -#define XST_FIFO_ERROR 7L /* an error occurred during an - operation with a FIFO such as - an underrun or overrun, this - error requires the device to - be reset */ -#define XST_RESET_ERROR 8L /* an error occurred which requires - the device to be reset */ -#define XST_DMA_ERROR 9L /* a DMA error occurred, this error - typically requires the device - using the DMA to be reset */ -#define XST_NOT_POLLED 10L /* the device is not configured for - polled mode operation */ -#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to put - the specified data into */ -#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large enough - to hold the expected data */ -#define XST_NO_DATA 13L /* there was no data available */ -#define XST_REGISTER_ERROR 14L /* a register did not contain the - expected value */ -#define XST_INVALID_PARAM 15L /* an invalid parameter was passed - into the function */ -#define XST_NOT_SGDMA 16L /* the device is not configured for - scatter-gather DMA operation */ -#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */ -#define XST_NO_CALLBACK 18L /* a callback has not yet been - registered */ -#define XST_NO_FEATURE 19L /* device is not configured with - the requested feature */ -#define XST_NOT_INTERRUPT 20L /* device is not configured for - interrupt mode operation */ -#define XST_DEVICE_BUSY 21L /* device is busy */ -#define XST_ERROR_COUNT_MAX 22L /* the error counters of a device - have maxed out */ -#define XST_IS_STARTED 23L /* used when part of device is - already started i.e. - sub channel */ -#define XST_IS_STOPPED 24L /* used when part of device is - already stopped i.e. - sub channel */ -#define XST_DATA_LOST 26L /* driver defined error */ -#define XST_RECV_ERROR 27L /* generic receive error */ -#define XST_SEND_ERROR 28L /* generic transmit error */ -#define XST_NOT_ENABLED 29L /* a requested service is not - available because it has not - been enabled */ - -/***************** Utility Component statuses 401 - 500 *********************/ - -#define XST_MEMTEST_FAILED 401L /* memory test failed */ - - -/***************** Common Components statuses 501 - 1000 *********************/ - -/********************* Packet Fifo statuses 501 - 510 ************************/ - -#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */ -#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */ -#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value - was invalid after reset */ -#define XST_PFIFO_ERROR 504L /* generic packet FIFO error */ -#define XST_PFIFO_DEADLOCK 505L /* packet FIFO is reporting - * empty and full simultaneously - */ - -/************************** DMA statuses 511 - 530 ***************************/ - -#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer - failed */ -#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value - was invalid after reset */ -#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains - no buffer descriptors ready - to be processed */ -#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */ -#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */ -#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of - the scatter gather list are - being used */ -#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer - descriptor which is to be - copied over in the scatter - list is locked */ -#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have been - put into the scatter gather - list to be commited */ -#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold - specified was larger than the - total # of buffer descriptors - in the scatter gather list */ -#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has - already been created */ -#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has - been created */ -#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which was - being started was not committed - to the list */ -#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to start - has already been used by the - hardware so it can't be reused - */ -#define XST_DMA_SG_LIST_ERROR 526L /* general purpose list access - error */ -#define XST_DMA_BD_ERROR 527L /* general buffer descriptor - error */ - -/************************** IPIF statuses 531 - 550 ***************************/ - -#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width - was passed into the function */ -#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at - reset was not valid */ -#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device interrupt - status register did not read - back correctly */ -#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status - register did not reset when - acked */ -#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable - register was not updated when - other registers changed */ -#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt - status register did not read - back correctly */ -#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status register - did not reset when acked */ -#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register was - not updated correctly when other - registers changed */ -#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending - register did not indicate the - expected value */ -#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID register - did not indicate the expected - value */ -#define XST_IPIF_ERROR 541L /* generic ipif error */ - -/****************** Device specific statuses 1001 - 4095 *********************/ - -/********************* Ethernet statuses 1001 - 1050 *************************/ - -#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big enough - * to hold the minimum number of - * buffers or descriptors */ -#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */ -#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */ -#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in progress */ -#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Driver is out of buffers */ -#define XST_EMAC_PARSE_ERROR 1006L /* Invalid driver init string */ -#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late - * collision on polled send */ - -/*********************** UART statuses 1051 - 1075 ***************************/ -#define XST_UART - -#define XST_UART_INIT_ERROR 1051L -#define XST_UART_START_ERROR 1052L -#define XST_UART_CONFIG_ERROR 1053L -#define XST_UART_TEST_FAIL 1054L -#define XST_UART_BAUD_ERROR 1055L -#define XST_UART_BAUD_RANGE 1056L - - -/************************ IIC statuses 1076 - 1100 ***************************/ - -#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */ -#define XST_IIC_BUS_BUSY 1077 /* bus found busy */ -#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with */ - /* general call address */ -#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg */ - /* value after reset not valid */ -#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design */ - /* value after reset not valid */ -#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design */ - /* value after reset not valid */ -#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design */ - /* value after reset not valid */ -#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register */ - /* didn't return value written */ -#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg */ - /* didn't return value written */ -#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg */ - /* didn't return value written */ -#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg */ - /* didn't return value written */ -#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg */ - /* didn't return written value */ -#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */ - -/*********************** ATMC statuses 1101 - 1125 ***************************/ - -#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM - controller hit the max value - which requires the statistics - to be cleared */ - -/*********************** Flash statuses 1126 - 1150 **************************/ - -#define XST_FLASH_BUSY 1126L /* Flash is erasing or programming - */ -#define XST_FLASH_READY 1127L /* Flash is ready for commands */ -#define XST_FLASH_ERROR 1128L /* Flash had detected an internal - error. Use XFlash_DeviceControl - to retrieve device specific codes - */ -#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase state - */ -#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write state - */ -#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by - driver */ -#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */ -#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */ -#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase operation - aborted due to a timeout */ -#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its - addressible range */ -#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */ -#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately from - write/erase function with - XFL_NON_BLOCKING_WRITE/ERASE - option cleared */ -#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */ - -/*********************** SPI statuses 1151 - 1175 ****************************/ - -#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave */ -#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */ -#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit register */ -#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive register */ -#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected yet */ -#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being - * selected */ -#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as master */ -#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as slave-only - */ -#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while disabled */ -#define XST_SPI_SLAVE_MODE 1160 /* device has been addressed as slave */ -#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /* device received data in slave mode */ - -#define XST_SPI_COMMAND_ERROR 1162 /* unrecognised command - qspi only */ - -/********************** OPB Arbiter statuses 1176 - 1200 *********************/ - -#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have either - * one master assigned to two or more - * priorities, or one master not - * assigned to any priority - */ -#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify the - * priority levels without first - * suspending the use of priority - * levels - */ -#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled but - * bus parking was not enabled - */ -#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed - * priority mode to allow the - * priorities to be changed - */ - -/************************ Intc statuses 1201 - 1225 **************************/ - -#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */ -#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */ - -/********************** TmrCtr statuses 1226 - 1250 **************************/ - -#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */ - -/********************** WdtTb statuses 1251 - 1275 ***************************/ - -#define XST_WDTTB_TIMER_FAILED 1251L - -/********************** PlbArb statuses 1276 - 1300 **************************/ - -#define XST_PLBARB_FAIL_SELFTEST 1276L - -/********************** Plb2Opb statuses 1301 - 1325 *************************/ - -#define XST_PLB2OPB_FAIL_SELFTEST 1301L - -/********************** Opb2Plb statuses 1326 - 1350 *************************/ - -#define XST_OPB2PLB_FAIL_SELFTEST 1326L - -/********************** SysAce statuses 1351 - 1360 **************************/ - -#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */ - -/********************** PCI Bridge statuses 1361 - 1375 **********************/ - -#define XST_PCI_INVALID_ADDRESS 1361L - -/********************** FlexRay constants 1400 - 1409 *************************/ - -#define XST_FR_TX_ERROR 1400 -#define XST_FR_TX_BUSY 1401 -#define XST_FR_BUF_LOCKED 1402 -#define XST_FR_NO_BUF 1403 - -/****************** USB constants 1410 - 1420 *******************************/ - -#define XST_USB_ALREADY_CONFIGURED 1410 -#define XST_USB_BUF_ALIGN_ERROR 1411 -#define XST_USB_NO_DESC_AVAILABLE 1412 -#define XST_USB_BUF_TOO_BIG 1413 -#define XST_USB_NO_BUF 1414 - -/****************** HWICAP constants 1421 - 1429 *****************************/ - -#define XST_HWICAP_WRITE_DONE 1421 - - -/****************** AXI VDMA constants 1430 - 1440 *****************************/ - -#define XST_VDMA_MISMATCH_ERROR 1430 - -/*********************** NAND Flash statuses 1441 - 1459 *********************/ - -#define XST_NAND_BUSY 1441L /* Flash is erasing or - * programming - */ -#define XST_NAND_READY 1442L /* Flash is ready for commands - */ -#define XST_NAND_ERROR 1443L /* Flash had detected an - * internal error. - */ -#define XST_NAND_PART_NOT_SUPPORTED 1444L /* Flash type not supported by - * driver - */ -#define XST_NAND_OPT_NOT_SUPPORTED 1445L /* Operation not supported - */ -#define XST_NAND_TIMEOUT_ERROR 1446L /* Programming or erase - * operation aborted due to a - * timeout - */ -#define XST_NAND_ADDRESS_ERROR 1447L /* Accessed flash outside its - * addressible range - */ -#define XST_NAND_ALIGNMENT_ERROR 1448L /* Write alignment error - */ -#define XST_NAND_PARAM_PAGE_ERROR 1449L /* Failed to read parameter - * page of the device - */ -#define XST_NAND_CACHE_ERROR 1450L /* Flash page buffer error - */ - -#define XST_NAND_WRITE_PROTECTED 1451L /* Flash is write protected - */ - -/**************************** Type Definitions *******************************/ - -typedef int XStatus; - -/***************** Macros (Inline Functions) Definitions *********************/ - - -/************************** Function Prototypes ******************************/ - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xstreamer.h b/thirdparty/libxil/include/xilinx/xstreamer.h deleted file mode 100644 index bbb65f0e9..000000000 --- a/thirdparty/libxil/include/xilinx/xstreamer.h +++ /dev/null @@ -1,333 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/* - * - * @file xstreamer.h -* @addtogroup llfifo_v5_0 -* @{ - * - * The Xilinx byte streamer for packet FIFOs. - * - *

Driver Description

- * - * This driver enables higher layer software to access a hardware FIFO using - * any alignment in the data buffers while preserving alignment for the hardware - * FIFO access. - * - * This driver treats send and receive channels separately, using different - * types of instance objects for each. - * - * This driver makes use of another FIFO driver to access the specific FIFO - * hardware through use of the routines passed into the Tx/RxInitialize - * routines. - * - *

Initialization

- * - * Send and receive channels are intialized separately. The receive channel is - * initiailzed using XStrm_RxInitialize(). The send channel is initialized - * using XStrm_TxInitialize(). - * - * - *

Usage

- * It is fairly simple to use the API provided by this byte streamer - * driver. The only somewhat tricky part is that the calling code must - * correctly call a couple routines in the right sequence for receive and - * transmit. - * - * This sequence is described here. Check the routine functional - * descriptions for information on how to use a specific API routine. - * - *

Receive

- * A frame is received by using the following sequence:
- * 1) call XStrm_RxGetLen() to get the length of the next incoming frame.
- * 2) call XStrm_Read() one or more times to read the number of bytes - * reported by XStrm_RxGetLen().
- * - * For example: - *
- * 	frame_len = XStrm_RxGetLen(&RxInstance);
- * 	while (frame_len) {
- * 		unsigned bytes = min(sizeof(buffer), frame_len);
- * 		XStrm_Read(&RxInstance, buffer, bytes);
- * 		// do something with buffer here
- * 		frame_len -= bytes;
- * 	}
- * 
- * - * Other restrictions on the sequence of API calls may apply depending on - * the specific FIFO driver used by this byte streamer driver. - * - *

Transmit

- * A frame is transmittted by using the following sequence:
- * 1) call XStrm_Write() one or more times to write all the of bytes in - * the next frame.
- * 2) call XStrm_TxSetLen() to begin the transmission of frame just - * written.
- * - * For example: - *
- * 	frame_left = frame_len;
- * 	while (frame_left) {
- * 		unsigned bytes = min(sizeof(buffer), frame_left);
- * 		XStrm_Write(&TxInstance, buffer, bytes);
- * 		// do something here to refill buffer
- * 	}
- * 	XStrm_TxSetLen(&RxInstance, frame_len);
- * 
- * - * Other restrictions on the sequence of API calls may apply depending on - * the specific FIFO driver used by this byte streamer driver. - * - *
- * MODIFICATION HISTORY:
- *
- * Ver   Who  Date     Changes
- * ----- ---- -------- -------------------------------------------------------
- * 1.00a jvb  10/12/06 First release
- * 1.02a jz   12/04/09  Hal phase 1 support
- * 2.00a hbm  01/20/10  Hal phase 1 support, bump up major release
- * 2.02a asa  12/28/11  The macro XStrm_IsRxInternalEmpty is changed to use
- *			FrmByteCnt instead of HeadIndex.
- * 
- * - *****************************************************************************/ -#ifndef XSTREAMER_H /* prevent circular inclusions */ -#define XSTREAMER_H /* by using preprocessor symbols */ - -/* force C linkage */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "xenv.h" -#include "xdebug.h" -#include "xil_types.h" - -/* - * key hole size in 32 bit words - */ -#define LARGEST_FIFO_KEYHOLE_SIZE_WORDS 4 - -/* - * This union is used simply to force a 32bit alignment on the - * buffer. Only the 'bytes' member is really used. - */ -union XStrm_AlignedBufferType { - u32 _words[LARGEST_FIFO_KEYHOLE_SIZE_WORDS]; - char bytes[LARGEST_FIFO_KEYHOLE_SIZE_WORDS * 4]; -}; - -typedef int(*XStrm_XferFnType) (void *FifoInstance, void *BufPtr, - unsigned WordCount); -typedef u32 (*XStrm_GetLenFnType) (void *FifoInstance); -typedef void (*XStrm_SetLenFnType) (void *FifoInstance, - u32 ByteCount); -typedef u32 (*XStrm_GetOccupancyFnType) (void *FifoInstance); -typedef u32 (*XStrm_GetVacancyFnType) (void *FifoInstance); - -/** - * This typedef defines a run-time instance of a receive byte-streamer. - */ -typedef struct XStrm_RxFifoStreamer { - union XStrm_AlignedBufferType AlignedBuffer; - unsigned HeadIndex; /**< HeadIndex is the index to the AlignedBuffer - * as bytes. - */ - unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes. - */ - unsigned FrmByteCnt; /**< FrmByteCnt is the number of bytes in the next - * Frame. - */ - void *FifoInstance; /**< FifoInstance is the FIFO driver instance to - * pass to ReadFn, GetLenFn, and GetOccupancyFn - * routines. - */ - XStrm_XferFnType ReadFn; /**< ReadFn is the routine the streamer - * uses to receive bytes from the Fifo. - */ - XStrm_GetLenFnType GetLenFn; /**< GetLenFn is the routine the streamer - * uses to initiate receive operations - * on the FIFO. - */ - XStrm_GetOccupancyFnType GetOccupancyFn; /**< GetOccupancyFn is the - * routine the streamer uses - * to get the occupancy from - * the FIFO. - */ -} XStrm_RxFifoStreamer; - -/** - * This typedef defines a run-time instance of a transmit byte-streamer. - */ -typedef struct XStrm_TxFifoStreamer { - union XStrm_AlignedBufferType AlignedBuffer; - unsigned TailIndex; /**< TailIndex is the index to the AlignedBuffer - * as bytes - */ - unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes. - */ - - void *FifoInstance; /**< FifoInstance is the FIFO driver instance to - * pass to WriteFn, SetLenFn, and GetVacancyFn - * routines. - */ - XStrm_XferFnType WriteFn; /**< WriteFn is the routine the streamer - * uses to transmit bytes to the Fifo. - */ - XStrm_SetLenFnType SetLenFn; /**< SetLenFn is the routine the streamer - * uses to initiate transmit operations - * on the FIFO. - */ - XStrm_GetVacancyFnType GetVacancyFn; /**< GetVaccancyFn is the routine - * the streamer uses to get the - * vacancy from the FIFO. - */ -} XStrm_TxFifoStreamer; - -/*****************************************************************************/ -/* -* -* XStrm_TxVacancy returns the number of unused 32-bit words available (vacancy) -* between the streamer, specified by InstancePtr, and the FIFO this -* streamer is using. -* -* @param InstancePtr references the streamer on which to operate. -* -* @return XStrm_TxVacancy returns the vacancy count in number of 32 bit words. -* -* @note -* -* C Signature: u32 XStrm_TxVacancy(XStrm_TxFifoStreamer *InstancePtr) -* -* The amount of bytes in the holding buffer (rounded up to whole 32-bit words) -* is subtracted from the vacancy value of FIFO this streamer is using. This is -* to ensure the caller can write the number words given in the return value and -* not overflow the FIFO. -* -******************************************************************************/ -#define XStrm_TxVacancy(InstancePtr) \ - (((*(InstancePtr)->GetVacancyFn)((InstancePtr)->FifoInstance)) - \ - (((InstancePtr)->TailIndex + 3) / 4)) - -/*****************************************************************************/ -/* -* -* XStrm_RxOccupancy returns the number of 32-bit words available (occupancy) to -* be read from the streamer, specified by InstancePtr, and FIFO this -* steamer is using. -* -* @param InstancePtr references the streamer on which to operate. -* -* @return XStrm_RxOccupancy returns the occupancy count in number of 32 bit -* words. -* -* @note -* -* C Signature: u32 XStrm_RxOccupancy(XStrm_RxFifoStreamer *InstancePtr) -* -* The amount of bytes in the holding buffer (rounded up to whole 32-bit words) -* is added to the occupancy value of FIFO this streamer is using. This is to -* ensure the caller will get a little more accurate occupancy value. -* -******************************************************************************/ -#ifdef DEBUG -extern u32 _xstrm_ro_value; -extern u32 _xstrm_buffered; -#define XStrm_RxOccupancy(InstancePtr) \ - (_xstrm_ro_value = ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)), \ - xdbg_printf(XDBG_DEBUG_FIFO_RX, "reg: %d; frmbytecnt: %d\n", \ - _xstrm_ro_value, (InstancePtr)->FrmByteCnt), \ - (((InstancePtr)->FrmByteCnt) ? \ - _xstrm_buffered = ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \ - 0), \ - xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered_bytes: %d\n", _xstrm_buffered), \ - xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered (rounded): %d\n", _xstrm_buffered), \ - (_xstrm_ro_value + _xstrm_buffered)) -#else -#define XStrm_RxOccupancy(InstancePtr) \ - ( \ - ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)) + \ - ( \ - ((InstancePtr)->FrmByteCnt) ? \ - ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \ - 0 \ - ) \ - ) -#endif - -/****************************************************************************/ -/* -* -* XStrm_IsRxInternalEmpty returns true if the streamer, specified by -* InstancePtr, is not holding any bytes in it's internal buffers. Note -* that this routine does not reflect information about the state of the -* FIFO used by this streamer. -* -* @param InstancePtr references the streamer on which to operate. -* -* @return XStrm_IsRxInternalEmpty returns TRUE when the streamer is not -* holding any bytes in it's internal buffers. Otherwise, -* XStrm_IsRxInternalEmpty returns FALSE. -* -* @note -* C-style signature: -* int XStrm_IsRxInternalEmpty(XStrm_RxFifoStreamer *InstancePtr) -* -*****************************************************************************/ -#define XStrm_IsRxInternalEmpty(InstancePtr) \ - (((InstancePtr)->FrmByteCnt == 0) ? TRUE : FALSE) - -void XStrm_RxInitialize(XStrm_RxFifoStreamer *InstancePtr, - unsigned FifoWidth, void *FifoInstance, - XStrm_XferFnType ReadFn, - XStrm_GetLenFnType GetLenFn, - XStrm_GetOccupancyFnType GetOccupancyFn); - -void XStrm_TxInitialize(XStrm_TxFifoStreamer *InstancePtr, - unsigned FifoWidth, void *FifoInstance, - XStrm_XferFnType WriteFn, - XStrm_SetLenFnType SetLenFn, - XStrm_GetVacancyFnType GetVacancyFn); - -void XStrm_TxSetLen(XStrm_TxFifoStreamer *InstancePtr, u32 Bytes); -void XStrm_Write(XStrm_TxFifoStreamer *InstancePtr, void *BufPtr, - unsigned bytes); - -u32 XStrm_RxGetLen(XStrm_RxFifoStreamer *InstancePtr); -void XStrm_Read(XStrm_RxFifoStreamer *InstancePtr, void *BufPtr, - unsigned bytes); - -#ifdef __cplusplus -} -#endif -#endif /* XSTREAMER_H end of preprocessor protection symbols */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xtmrctr.h b/thirdparty/libxil/include/xilinx/xtmrctr.h deleted file mode 100644 index 5b8238043..000000000 --- a/thirdparty/libxil/include/xilinx/xtmrctr.h +++ /dev/null @@ -1,303 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xtmrctr.h -* @addtogroup tmrctr_v4_0 -* @{ -* @details -* -* The Xilinx timer/counter component. This component supports the Xilinx -* timer/counter. More detailed description of the driver operation can -* be found in the xtmrctr.c file. -* -* The Xilinx timer/counter supports the following features: -* - Polled mode. -* - Interrupt driven mode -* - enabling and disabling specific timers -* - PWM operation -* - Cascade Operation (This is to be used for getting a 64 bit timer and this -* feature is present in the latest versions of the axi_timer IP) -* -* The driver does not currently support the PWM operation of the device. -* -* The timer counter operates in 2 primary modes, compare and capture. In -* either mode, the timer counter may count up or down, with up being the -* default. -* -* Compare mode is typically used for creating a single time period or multiple -* repeating time periods in the auto reload mode, such as a periodic interrupt. -* When started, the timer counter loads an initial value, referred to as the -* compare value, into the timer counter and starts counting down or up. The -* timer counter expires when it rolls over/under depending upon the mode of -* counting. An external compare output signal may be configured such that a -* pulse is generated with this signal when it hits the compare value. -* -* Capture mode is typically used for measuring the time period between -* external events. This mode uses an external capture input signal to cause -* the value of the timer counter to be captured. When started, the timer -* counter loads an initial value, referred to as the compare value, - -* The timer can be configured to either cause an interrupt when the count -* reaches the compare value in compare mode or latch the current count -* value in the capture register when an external input is asserted -* in capture mode. The external capture input can be enabled/disabled using the -* XTmrCtr_SetOptions function. While in compare mode, it is also possible to -* drive an external output when the compare value is reached in the count -* register The external compare output can be enabled/disabled using the -* XTmrCtr_SetOptions function. -* -* Interrupts -* -* It is the responsibility of the application to connect the interrupt -* handler of the timer/counter to the interrupt source. The interrupt -* handler function, XTmrCtr_InterruptHandler, is visible such that the user -* can connect it to the interrupt source. Note that this interrupt handler -* does not provide interrupt context save and restore processing, the user -* must perform this processing. -* -* The driver services interrupts and passes timeouts to the upper layer -* software through callback functions. The upper layer software must register -* its callback functions during initialization. The driver requires callback -* functions for timers. -* -* @note -* The default settings for the timers are: -* - Interrupt generation disabled -* - Count up mode -* - Compare mode -* - Hold counter (will not reload the timer) -* - External compare output disabled -* - External capture input disabled -* - Pulse width modulation disabled -* - Timer disabled, waits for Start function to be called -*

-* A timer counter device may contain multiple timer counters. The symbol -* XTC_DEVICE_TIMER_COUNT defines the number of timer counters in the device. -* The device currently contains 2 timer counters. -*

-* This driver is intended to be RTOS and processor independent. It works with -* physical addresses only. Any needs for dynamic memory management, threads -* or thread mutual exclusion, virtual memory, or cache control must be -* satisfied by the layer above this driver. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00a ecm  08/16/01 First release
-* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
-* 1.10b mta  03/21/07 Updated to new coding style.
-* 1.11a sdm  08/22/08 Removed support for static interrupt handlers from the MDD
-*		      file
-* 2.00a ktn  10/30/09 Updated to use HAL API's. _m is removed from all the macro
-*		      definitions.
-* 2.01a ktn  07/12/10 Renamed the macro XTimerCtr_ReadReg as XTmrCtr_ReadReg
-*		      for naming consistency (CR 559142).
-* 2.02a sdm  09/28/10 Updated the driver tcl to generate the xparameters
-*		      for the timer clock frequency (CR 572679).
-* 2.03a rvo  11/30/10 Added check to see if interrupt is enabled before further
-*		      processing for CR 584557.
-* 2.04a sdm  07/12/11 Added support for cascade mode operation.
-* 		      The cascade mode of operation is present in the latest
-*		      versions of the axi_timer IP. Please check the HW
-*		      Datasheet to see whether this feature is present in the
-*		      version of the IP that you are using.
-* 2.05a adk  15/05/13 Fixed the CR:693066
-*		      Added the IsStartedTmrCtr0/IsStartedTmrCtr1 members to the
-*		      XTmrCtr instance structure.
-*		      The IsStartedTmrCtrX will be assigned XIL_COMPONENT_IS_STARTED in
-*		      the XTmrCtr_Start function.
-*		      The IsStartedTmrCtrX will be cleared in the XTmrCtr_Stop function.
-*		      There will be no Initialization done in the
-*		      XTmrCtr_Initialize if both the timers have already started and
-*		      the XST_DEVICE_IS_STARTED Status is returned.
-*		      Removed the logic in the XTmrCtr_Initialize function
-*		      which was checking the Register Value to know whether
-*		      a timer has started or not.
-* 3.0   adk  19/12/13 Updated as per the New Tcl API's
-* 4.0   als  09/30/15 Updated initialization API.
-* 
-* -******************************************************************************/ - -#ifndef XTMRCTR_H /* prevent circular inclusions */ -#define XTMRCTR_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_types.h" -#include "xil_assert.h" -#include "xstatus.h" -#include "xtmrctr_l.h" - -/************************** Constant Definitions *****************************/ - -/** - * @name Configuration options - * These options are used in XTmrCtr_SetOptions() and XTmrCtr_GetOptions() - * @{ - */ -/** - * Used to configure the timer counter device. - *
- * XTC_CASCADE_MODE_OPTION	Enables the Cascade Mode only valid for TCSRO.
- * XTC_ENABLE_ALL_OPTION	Enables all timer counters at once.
- * XTC_DOWN_COUNT_OPTION	Configures the timer counter to count down from
- *				start value, the default is to count up.
- * XTC_CAPTURE_MODE_OPTION	Configures the timer to capture the timer
- *				counter value when the external capture line is
- *				asserted. The default mode is compare mode.
- * XTC_INT_MODE_OPTION		Enables the timer counter interrupt output.
- * XTC_AUTO_RELOAD_OPTION	In compare mode, configures the timer counter to
- *				reload from the compare value. The default mode
- *				causes the timer counter to hold when the
- *				compare value is hit.
- *				In capture mode, configures the timer counter to
- *				not hold the previous capture value if a new
- *				event occurs. The default mode cause the timer
- *				counter to hold the capture value until
- *				recognized.
- * XTC_EXT_COMPARE_OPTION	Enables the external compare output signal.
- * 
- */ -#define XTC_CASCADE_MODE_OPTION 0x00000080UL -#define XTC_ENABLE_ALL_OPTION 0x00000040UL -#define XTC_DOWN_COUNT_OPTION 0x00000020UL -#define XTC_CAPTURE_MODE_OPTION 0x00000010UL -#define XTC_INT_MODE_OPTION 0x00000008UL -#define XTC_AUTO_RELOAD_OPTION 0x00000004UL -#define XTC_EXT_COMPARE_OPTION 0x00000002UL -/*@}*/ - -/**************************** Type Definitions *******************************/ - -/** - * This typedef contains configuration information for the device. - */ -typedef struct { - u16 DeviceId; /**< Unique ID of device */ - u32 BaseAddress; /**< Register base address */ - u32 SysClockFreqHz; /**< The AXI bus clock frequency */ -} XTmrCtr_Config; - -/** - * Signature for the callback function. - * - * @param CallBackRef is a callback reference passed in by the upper layer - * when setting the callback functions, and passed back to the - * upper layer when the callback is invoked. Its type is - * unimportant to the driver, so it is a void pointer. - * @param TmrCtrNumber is the number of the timer/counter within the - * device. The device typically contains at least two - * timer/counters. The timer number is a zero based number with a - * range of 0 to (XTC_DEVICE_TIMER_COUNT - 1). - */ -typedef void (*XTmrCtr_Handler) (void *CallBackRef, u8 TmrCtrNumber); - - -/** - * Timer/Counter statistics - */ -typedef struct { - u32 Interrupts; /**< The number of interrupts that have occurred */ -} XTmrCtrStats; - -/** - * The XTmrCtr driver instance data. The user is required to allocate a - * variable of this type for every timer/counter device in the system. A - * pointer to a variable of this type is then passed to the driver API - * functions. - */ -typedef struct { - XTmrCtr_Config Config; /**< Core configuration. */ - XTmrCtrStats Stats; /**< Component Statistics */ - u32 BaseAddress; /**< Base address of registers */ - u32 IsReady; /**< Device is initialized and ready */ - u32 IsStartedTmrCtr0; /**< Is Timer Counter 0 started */ - u32 IsStartedTmrCtr1; /**< Is Timer Counter 1 started */ - - XTmrCtr_Handler Handler; /**< Callback function */ - void *CallBackRef; /**< Callback reference for handler */ -} XTmrCtr; - - -/***************** Macros (Inline Functions) Definitions *********************/ - - -/************************** Function Prototypes ******************************/ - -/* Required functions, in file xtmrctr.c */ -void XTmrCtr_CfgInitialize(XTmrCtr *InstancePtr, XTmrCtr_Config *ConfigPtr, - u32 EffectiveAddr); -int XTmrCtr_InitHw(XTmrCtr *InstancePtr); -int XTmrCtr_Initialize(XTmrCtr * InstancePtr, u16 DeviceId); -void XTmrCtr_Start(XTmrCtr * InstancePtr, u8 TmrCtrNumber); -void XTmrCtr_Stop(XTmrCtr * InstancePtr, u8 TmrCtrNumber); -u32 XTmrCtr_GetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber); -void XTmrCtr_SetResetValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber, - u32 ResetValue); -u32 XTmrCtr_GetCaptureValue(XTmrCtr * InstancePtr, u8 TmrCtrNumber); -int XTmrCtr_IsExpired(XTmrCtr * InstancePtr, u8 TmrCtrNumber); -void XTmrCtr_Reset(XTmrCtr * InstancePtr, u8 TmrCtrNumber); - -/* Lookup configuration in xtmrctr_sinit.c */ -XTmrCtr_Config *XTmrCtr_LookupConfig(u16 DeviceId); - -/* Functions for options, in file xtmrctr_options.c */ -void XTmrCtr_SetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber, u32 Options); -u32 XTmrCtr_GetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber); - -/* Functions for statistics, in file xtmrctr_stats.c */ -void XTmrCtr_GetStats(XTmrCtr * InstancePtr, XTmrCtrStats * StatsPtr); -void XTmrCtr_ClearStats(XTmrCtr * InstancePtr); - -/* Functions for self-test, in file xtmrctr_selftest.c */ -int XTmrCtr_SelfTest(XTmrCtr * InstancePtr, u8 TmrCtrNumber); - -/* Functions for interrupts, in file xtmrctr_intr.c */ -void XTmrCtr_SetHandler(XTmrCtr * InstancePtr, XTmrCtr_Handler FuncPtr, - void *CallBackRef); -void XTmrCtr_InterruptHandler(void *InstancePtr); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xtmrctr_i.h b/thirdparty/libxil/include/xilinx/xtmrctr_i.h deleted file mode 100644 index 6cbbc0a46..000000000 --- a/thirdparty/libxil/include/xilinx/xtmrctr_i.h +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xtmrctr_i.h -* @addtogroup tmrctr_v3_0 -* @{ -* -* This file contains data which is shared between files internal to the -* XTmrCtr component. It is intended for internal use only. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00b jhl  02/06/02 First release
-* 1.10b mta  03/21/07 Updated to new coding style
-* 2.00a ktn  10/30/09 _m is removed from all the macro definitions.
-* 
-* -******************************************************************************/ - -#ifndef XTMRCTR_I_H /* prevent circular inclusions */ -#define XTMRCTR_I_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_types.h" - -/************************** Constant Definitions *****************************/ - - -/************************** Function Prototypes ******************************/ - - -/************************** Variable Definitions *****************************/ - -extern u8 XTmrCtr_Offsets[]; - -#ifdef __cplusplus -} -#endif - -#endif -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xtmrctr_l.h b/thirdparty/libxil/include/xilinx/xtmrctr_l.h deleted file mode 100644 index f5fd773ee..000000000 --- a/thirdparty/libxil/include/xilinx/xtmrctr_l.h +++ /dev/null @@ -1,429 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xtmrctr_l.h -* @addtogroup tmrctr_v4_0 -* @{ -* -* This header file contains identifiers and low-level driver functions (or -* macros) that can be used to access the device. The user should refer to the -* hardware device specification for more details of the device operation. -* High-level driver functions are defined in xtmrctr.h. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver   Who  Date     Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00b jhl  04/24/02 First release
-* 1.10b mta  03/21/07 Updated to new coding style
-* 2.00a ktn  10/30/09 Updated to use HAL API's. _m is removed from all the macro
-*		      definitions.
-* 2.01a ktn  07/12/10 Renamed the macro XTimerCtr_ReadReg as XTmrCtr_ReadReg
-*		      for naming consistency (CR 559142).
-* 2.04a sdm  07/12/11 Added the CASC mode bit in the TCSRO register for the
-*		      cascade mode operation.
-*		      The cascade mode of operation is present in the latest
-*		      versions of the axi_timer IP. Please check the HW
-*		      Datasheet to see whether this feature is present in the
-*		      version of the IP that you are using.
-* 
-* -******************************************************************************/ - -#ifndef XTMRCTR_L_H /* prevent circular inclusions */ -#define XTMRCTR_L_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xil_types.h" -#include "xil_io.h" - -/************************** Constant Definitions *****************************/ - -/** - * Defines the number of timer counters within a single hardware device. This - * number is not currently parameterized in the hardware but may be in the - * future. - */ -#define XTC_DEVICE_TIMER_COUNT 2 - -/* Each timer counter consumes 16 bytes of address space */ - -#define XTC_TIMER_COUNTER_OFFSET 16 - -/** @name Register Offset Definitions - * Register offsets within a timer counter, there are multiple - * timer counters within a single device - * @{ - */ - -#define XTC_TCSR_OFFSET 0 /**< Control/Status register */ -#define XTC_TLR_OFFSET 4 /**< Load register */ -#define XTC_TCR_OFFSET 8 /**< Timer counter register */ - -/* @} */ - -/** @name Control Status Register Bit Definitions - * Control Status Register bit masks - * Used to configure the timer counter device. - * @{ - */ - -#define XTC_CSR_CASC_MASK 0x00000800 /**< Cascade Mode */ -#define XTC_CSR_ENABLE_ALL_MASK 0x00000400 /**< Enables all timer - counters */ -#define XTC_CSR_ENABLE_PWM_MASK 0x00000200 /**< Enables the Pulse Width - Modulation */ -#define XTC_CSR_INT_OCCURED_MASK 0x00000100 /**< If bit is set, an - interrupt has occured. - If set and '1' is - written to this bit - position, bit is - cleared. */ -#define XTC_CSR_ENABLE_TMR_MASK 0x00000080 /**< Enables only the - specific timer */ -#define XTC_CSR_ENABLE_INT_MASK 0x00000040 /**< Enables the interrupt - output. */ -#define XTC_CSR_LOAD_MASK 0x00000020 /**< Loads the timer using - the load value provided - earlier in the Load - Register, - XTC_TLR_OFFSET. */ -#define XTC_CSR_AUTO_RELOAD_MASK 0x00000010 /**< In compare mode, - configures - the timer counter to - reload from the - Load Register. The - default mode - causes the timer counter - to hold when the compare - value is hit. In capture - mode, configures the - timer counter to not - hold the previous - capture value if a new - event occurs. The - default mode cause the - timer counter to hold - the capture value until - recognized. */ -#define XTC_CSR_EXT_CAPTURE_MASK 0x00000008 /**< Enables the - external input - to the timer counter. */ -#define XTC_CSR_EXT_GENERATE_MASK 0x00000004 /**< Enables the - external generate output - for the timer. */ -#define XTC_CSR_DOWN_COUNT_MASK 0x00000002 /**< Configures the timer - counter to count down - from start value, the - default is to count - up.*/ -#define XTC_CSR_CAPTURE_MODE_MASK 0x00000001 /**< Enables the timer to - capture the timer - counter value when the - external capture line is - asserted. The default - mode is compare mode.*/ -/* @} */ - -/**************************** Type Definitions *******************************/ - -extern u8 XTmrCtr_Offsets[]; - -/***************** Macros (Inline Functions) Definitions *********************/ - -/*****************************************************************************/ -/** -* Read one of the timer counter registers. -* -* @param BaseAddress contains the base address of the timer counter -* device. -* @param TmrCtrNumber contains the specific timer counter within the -* device, a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* @param RegOffset contains the offset from the 1st register of the timer -* counter to select the specific register of the timer counter. -* -* @return The value read from the register, a 32 bit value. -* -* @note C-Style signature: -* u32 XTmrCtr_ReadReg(u32 BaseAddress, u8 TimerNumber, - unsigned RegOffset); -******************************************************************************/ -#define XTmrCtr_ReadReg(BaseAddress, TmrCtrNumber, RegOffset) \ - Xil_In32((BaseAddress) + XTmrCtr_Offsets[(TmrCtrNumber)] + \ - (RegOffset)) - -#ifndef XTimerCtr_ReadReg -#define XTimerCtr_ReadReg XTmrCtr_ReadReg -#endif - -/*****************************************************************************/ -/** -* Write a specified value to a register of a timer counter. -* -* @param BaseAddress is the base address of the timer counter device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* @param RegOffset contain the offset from the 1st register of the timer -* counter to select the specific register of the timer counter. -* @param ValueToWrite is the 32 bit value to be written to the register. -* -* @note C-Style signature: -* void XTmrCtr_WriteReg(u32 BaseAddress, u8 TimerNumber, -* unsigned RegOffset, u32 ValueToWrite); -******************************************************************************/ -#define XTmrCtr_WriteReg(BaseAddress, TmrCtrNumber, RegOffset, ValueToWrite)\ - Xil_Out32(((BaseAddress) + XTmrCtr_Offsets[(TmrCtrNumber)] + \ - (RegOffset)), (ValueToWrite)) - -/****************************************************************************/ -/** -* -* Set the Control Status Register of a timer counter to the specified value. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* @param RegisterValue is the 32 bit value to be written to the register. -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_SetControlStatusReg(u32 BaseAddress, -* u8 TmrCtrNumber,u32 RegisterValue); -*****************************************************************************/ -#define XTmrCtr_SetControlStatusReg(BaseAddress, TmrCtrNumber, RegisterValue)\ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (RegisterValue)) - -/****************************************************************************/ -/** -* -* Get the Control Status Register of a timer counter. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, -* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return The value read from the register, a 32 bit value. -* -* @note C-Style signature: -* u32 XTmrCtr_GetControlStatusReg(u32 BaseAddress, -* u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_GetControlStatusReg(BaseAddress, TmrCtrNumber) \ - XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET) - -/****************************************************************************/ -/** -* -* Get the Timer Counter Register of a timer counter. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, -* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return The value read from the register, a 32 bit value. -* -* @note C-Style signature: -* u32 XTmrCtr_GetTimerCounterReg(u32 BaseAddress, -* u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_GetTimerCounterReg(BaseAddress, TmrCtrNumber) \ - XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TCR_OFFSET) \ - -/****************************************************************************/ -/** -* -* Set the Load Register of a timer counter to the specified value. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* @param RegisterValue is the 32 bit value to be written to the register. -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_SetLoadReg(u32 BaseAddress, u8 TmrCtrNumber, -* u32 RegisterValue); -*****************************************************************************/ -#define XTmrCtr_SetLoadReg(BaseAddress, TmrCtrNumber, RegisterValue) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TLR_OFFSET, \ - (RegisterValue)) - -/****************************************************************************/ -/** -* -* Get the Load Register of a timer counter. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return The value read from the register, a 32 bit value. -* -* @note C-Style signature: -* u32 XTmrCtr_GetLoadReg(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_GetLoadReg(BaseAddress, TmrCtrNumber) \ -XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), XTC_TLR_OFFSET) - -/****************************************************************************/ -/** -* -* Enable a timer counter such that it starts running. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_Enable(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_Enable(BaseAddress, TmrCtrNumber) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (XTmrCtr_ReadReg((BaseAddress), ( TmrCtrNumber), \ - XTC_TCSR_OFFSET) | XTC_CSR_ENABLE_TMR_MASK)) - -/****************************************************************************/ -/** -* -* Disable a timer counter such that it stops running. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, -* a zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_Disable(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_Disable(BaseAddress, TmrCtrNumber) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber),\ - XTC_TCSR_OFFSET) & ~ XTC_CSR_ENABLE_TMR_MASK)) - -/****************************************************************************/ -/** -* -* Enable the interrupt for a timer counter. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_EnableIntr(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_EnableIntr(BaseAddress, TmrCtrNumber) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \ - XTC_TCSR_OFFSET) | XTC_CSR_ENABLE_INT_MASK)) - -/****************************************************************************/ -/** -* -* Disable the interrupt for a timer counter. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_DisableIntr(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_DisableIntr(BaseAddress, TmrCtrNumber) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \ - XTC_TCSR_OFFSET) & ~ XTC_CSR_ENABLE_INT_MASK)) - -/****************************************************************************/ -/** -* -* Cause the timer counter to load it's Timer Counter Register with the value -* in the Load Register. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @return None. -* -* @note C-Style signature: -* void XTmrCtr_LoadTimerCounterReg(u32 BaseAddress, - u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_LoadTimerCounterReg(BaseAddress, TmrCtrNumber) \ - XTmrCtr_WriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \ - (XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber),\ - XTC_TCSR_OFFSET) | XTC_CSR_LOAD_MASK)) - -/****************************************************************************/ -/** -* -* Determine if a timer counter event has occurred. Events are defined to be -* when a capture has occurred or the counter has roller over. -* -* @param BaseAddress is the base address of the device. -* @param TmrCtrNumber is the specific timer counter within the device, a -* zero based number, 0 - (XTC_DEVICE_TIMER_COUNT - 1). -* -* @note C-Style signature: -* int XTmrCtr_HasEventOccurred(u32 BaseAddress, u8 TmrCtrNumber); -*****************************************************************************/ -#define XTmrCtr_HasEventOccurred(BaseAddress, TmrCtrNumber) \ - ((XTmrCtr_ReadReg((BaseAddress), (TmrCtrNumber), \ - XTC_TCSR_OFFSET) & XTC_CSR_INT_OCCURED_MASK) == \ - XTC_CSR_INT_OCCURED_MASK) - -/************************** Function Prototypes ******************************/ -/************************** Variable Definitions *****************************/ -#ifdef __cplusplus -} -#endif -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xutil.h b/thirdparty/libxil/include/xilinx/xutil.h deleted file mode 100644 index 082738e34..000000000 --- a/thirdparty/libxil/include/xilinx/xutil.h +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* -* @file xutil.h -* @addtogroup common_v1_00_a -* @{ -* -* This file contains utility functions such as memory test functions. -* -* Memory test description -* -* A subset of the memory tests can be selected or all of the tests can be run -* in order. If there is an error detected by a subtest, the test stops and the -* failure code is returned. Further tests are not run even if all of the tests -* are selected. -* -* Subtest descriptions: -*
-* XUT_ALLMEMTESTS:
-*       Runs all of the following tests
-*
-* XUT_INCREMENT:
-*       Incrementing Value Test.
-*       This test starts at 'XUT_MEMTEST_INIT_VALUE' and uses the incrementing
-*       value as the test value for memory.
-*
-* XUT_WALKONES:
-*       Walking Ones Test.
-*       This test uses a walking '1' as the test value for memory.
-*       location 1 = 0x00000001
-*       location 2 = 0x00000002
-*       ...
-*
-* XUT_WALKZEROS:
-*       Walking Zero's Test.
-*       This test uses the inverse value of the walking ones test
-*       as the test value for memory.
-*       location 1 = 0xFFFFFFFE
-*       location 2 = 0xFFFFFFFD
-*       ...
-*
-* XUT_INVERSEADDR:
-*       Inverse Address Test.
-*       This test uses the inverse of the address of the location under test
-*       as the test value for memory.
-*
-* XUT_FIXEDPATTERN:
-*       Fixed Pattern Test.
-*       This test uses the provided patters as the test value for memory.
-*       If zero is provided as the pattern the test uses '0xDEADBEEF".
-* 
-* -* WARNING -* -* The tests are DESTRUCTIVE. Run before any initialized memory spaces -* have been set up. -* -* The address, Addr, provided to the memory tests is not checked for -* validity except for the NULL case. It is possible to provide a code-space -* pointer for this test to start with and ultimately destroy executable code -* causing random failures. -* -* @note -* -* Used for spaces where the address range of the region is smaller than -* the data width. If the memory range is greater than 2 ** width, -* the patterns used in XUT_WALKONES and XUT_WALKZEROS will repeat on a -* boundry of a power of two making it more difficult to detect addressing -* errors. The XUT_INCREMENT and XUT_INVERSEADDR tests suffer the same -* problem. Ideally, if large blocks of memory are to be tested, break -* them up into smaller regions of memory to allow the test patterns used -* not to repeat over the region tested. -* -*
-* MODIFICATION HISTORY:
-*
-* Ver    Who    Date    Changes
-* ----- ---- -------- -----------------------------------------------
-* 1.00a ecm  11/01/01 First release
-* 1.00a xd   11/03/04 Improved support for doxygen.
-* 
-* -******************************************************************************/ - -#ifndef XUTIL_H /* prevent circular inclusions */ -#define XUTIL_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ -#include "xbasic_types.h" -#include "xstatus.h" - -/************************** Constant Definitions *****************************/ - - -/**************************** Type Definitions *******************************/ - -/* xutil_memtest defines */ - -#define XUT_MEMTEST_INIT_VALUE 1 - -/** @name Memory subtests - * @{ - */ -/** - * See the detailed description of the subtests in the file description. - */ -#define XUT_ALLMEMTESTS 0 -#define XUT_INCREMENT 1 -#define XUT_WALKONES 2 -#define XUT_WALKZEROS 3 -#define XUT_INVERSEADDR 4 -#define XUT_FIXEDPATTERN 5 -#define XUT_MAXTEST XUT_FIXEDPATTERN -/* @} */ - -/***************** Macros (Inline Functions) Definitions *********************/ - - -/************************** Function Prototypes ******************************/ - -/* xutil_memtest prototypes */ - -int XUtil_MemoryTest32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest); -int XUtil_MemoryTest16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest); -int XUtil_MemoryTest8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/include/xilinx/xversion.h b/thirdparty/libxil/include/xilinx/xversion.h deleted file mode 100644 index 8dad9824c..000000000 --- a/thirdparty/libxil/include/xilinx/xversion.h +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -/*****************************************************************************/ -/** -* @file xversion.h -* @addtogroup common_v1_00_a -* @{ -* -* This file contains the interface for the XVersion component. This -* component represents a version ID. It is encapsulated within a component -* so that it's type and implementation can change without affecting users of -* it. -* -* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z -* X is the major revision, YY is the minor revision, and Z is the -* compatability revision. -* -* Packed versions are also utilized for the configuration ROM such that -* memory is minimized. A packed version consumes only 16 bits and is -* formatted as follows. -* -*
-* Revision                  Range       Bit Positions
-*
-* Major Revision            0 - 9       Bits 15 - 12
-* Minor Revision            0 - 99      Bits 11 - 5
-* Compatability Revision    a - z       Bits 4 - 0
-*
-* MODIFICATION HISTORY:
-*
-* Ver   Who    Date   Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a xd   11/03/04 Improved support for doxygen.
-* 
-* -******************************************************************************/ - -#ifndef XVERSION_H /* prevent circular inclusions */ -#define XVERSION_H /* by using protection macros */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************** Include Files *********************************/ - -#include "xbasic_types.h" -#include "xstatus.h" - -/************************** Constant Definitions *****************************/ - - -/**************************** Type Definitions *******************************/ - -/* the following data type is used to hold a null terminated version string - * consisting of the following format, "X.YYX" - */ -typedef char XVersion[6]; - -/***************** Macros (Inline Functions) Definitions *********************/ - - -/************************** Function Prototypes ******************************/ - -void XVersion_UnPack(XVersion *InstancePtr, u16 PackedVersion); - -int XVersion_Pack(XVersion *InstancePtr, u16 *PackedVersion); - -int XVersion_IsEqual(XVersion *InstancePtr, XVersion *VersionPtr); - -void XVersion_ToString(XVersion *InstancePtr, char *StringPtr); - -int XVersion_FromString(XVersion *InstancePtr, char *StringPtr); - -void XVersion_Copy(XVersion *InstancePtr, XVersion *VersionPtr); - -#ifdef __cplusplus -} -#endif - -#endif /* end of protection macro */ -/** @} */ diff --git a/thirdparty/libxil/libxil.pc.in b/thirdparty/libxil/libxil.pc.in deleted file mode 100644 index 5f98b236a..000000000 --- a/thirdparty/libxil/libxil.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -includedir=${prefix}/include -libdir=${exec_prefix}/lib - -Name: xil -Description: Xilinx standalone drivers -Version: 1.0.0 -Cflags: -I${includedir} -Libs: -L${libdir} -lxil \ No newline at end of file diff --git a/thirdparty/libxil/orig/README.md b/thirdparty/libxil/orig/README.md deleted file mode 100644 index 16edb5122..000000000 --- a/thirdparty/libxil/orig/README.md +++ /dev/null @@ -1 +0,0 @@ -Those drivers are taken from https://github.com/Xilinx/embeddedsw \ No newline at end of file diff --git a/thirdparty/libxil/orig/axidma_v9_0/data/axidma.mdd b/thirdparty/libxil/orig/axidma_v9_0/data/axidma.mdd deleted file mode 100644 index 773a39d3c..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/data/axidma.mdd +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################### -# -# Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# Use of the Software is limited solely to applications: -# (a) running on a Xilinx device, or -# (b) that interact with a Xilinx device through a bus or interconnect. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -# Except as contained in this notice, the name of the Xilinx shall not be used -# in advertising or otherwise to promote the sale, use or other dealings in -# this Software without prior written authorization from Xilinx. -# -############################################################################## - -OPTION psf_version = 2.1; - -BEGIN driver axidma - - OPTION supported_peripherals = (axi_dma_v[3-9]_[0-9][0-9]_[a-z] axi_dma_v[3-9]_[0-9]); - OPTION driver_state = ACTIVE; - OPTION copyfiles = all; - OPTION VERSION = 9.0; - OPTION NAME = axidma; - -END driver diff --git a/thirdparty/libxil/orig/axidma_v9_0/data/axidma.tcl b/thirdparty/libxil/orig/axidma_v9_0/data/axidma.tcl deleted file mode 100644 index f0f806f76..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/data/axidma.tcl +++ /dev/null @@ -1,208 +0,0 @@ -############################################################################### -# -# Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# Use of the Software is limited solely to applications: -# (a) running on a Xilinx device, or -# (b) that interact with a Xilinx device through a bus or interconnect. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -# Except as contained in this notice, the name of the Xilinx shall not be used -# in advertising or otherwise to promote the sale, use or other dealings in -# this Software without prior written authorization from Xilinx. -# -# MODIFICATION HISTORY: -# Ver Who Date Changes -# -------- ------ -------- ---------------------------------------------------- -# 8.0 adk 12/10/13 Updated as per the New Tcl API's -############################################################################## - -#uses "xillib.tcl" - -set periph_ninstances 0 - -proc generate {drv_handle} { - ::hsi::utils::define_include_file $drv_handle "xparameters.h" "XAxiDma" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S_DRE" "C_INCLUDE_S2MM_DRE" "C_INCLUDE_MM2S" "C_INCLUDE_S2MM" "C_M_AXI_MM2S_DATA_WIDTH" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_ENABLE_MULTI_CHANNEL" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA" "c_addr_width" - ::hsi::utils::define_canonical_xpars $drv_handle "xparameters.h" "AxiDma" "DEVICE_ID" "C_BASEADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S" "C_INCLUDE_MM2S_DRE" "C_M_AXI_MM2S_DATA_WIDTH" "C_INCLUDE_S2MM" "C_INCLUDE_S2MM_DRE" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_ENABLE_MULTI_CHANNEL" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA" "c_addr_width" - ::hsi::utils::define_config_file $drv_handle "xaxidma_g.c" "XAxiDma" "DEVICE_ID" "C_BASEADDR" "C_SG_INCLUDE_STSCNTRL_STRM" "C_INCLUDE_MM2S" "C_INCLUDE_MM2S_DRE" "C_M_AXI_MM2S_DATA_WIDTH" "C_INCLUDE_S2MM" "C_INCLUDE_S2MM_DRE" "C_M_AXI_S2MM_DATA_WIDTH" "C_INCLUDE_SG" "C_NUM_MM2S_CHANNELS" "C_NUM_S2MM_CHANNELS" "C_MM2S_BURST_SIZE" "C_S2MM_BURST_SIZE" "C_MICRO_DMA" "c_addr_width" -} - -# -# Given a list of arguments, define them all in an include file. -# Handles mpd and mld parameters, as well as the special parameters NUM_INSTANCES, -# DEVICE_ID -# Will not work for a processor. -# - -proc xdefine_dma_include_file {drv_handle file_name drv_string args} { - # Open include file - set file_handle [xopen_include_file $file_name] - - # Get all peripherals connected to this driver - set periphs [xget_sw_iplist_for_driver $drv_handle] - - # Handle special cases - set arg "NUM_INSTANCES" - set posn [lsearch -exact $args $arg] - if {$posn > -1} { - puts $file_handle "/* Definitions for driver [string toupper [get_property NAME $drv_handle]] */" - # Define NUM_INSTANCES - puts $file_handle "#define [xget_dname $drv_string $arg] [llength $periphs]" - set args [lreplace $args $posn $posn] - } - # Check if it is a driver parameter - - lappend newargs - foreach arg $args { - set value [get_property CONFIG.$arg $drv_handle] - if {[llength $value] == 0} { - lappend newargs $arg - } else { - puts $file_handle "#define [xget_dname $drv_string $arg] [get_property CONFIG.$arg $drv_handle]" - } - } - set args $newargs - - # Print all parameters for all peripherals - set device_id 0 - foreach periph $periphs { - puts $file_handle "" - puts $file_handle "/* Definitions for peripheral [string toupper [get_property NAME $periph]] */" - foreach arg $args { - if {[string compare -nocase "DEVICE_ID" $arg] == 0} { - set value $device_id - incr device_id - } else { - set value [xget_param_value $periph $arg] - if {[string compare -nocase $arg "C_INCLUDE_SG"] == 0} { - if {[llength $value] == 0} { - set value 1 - } - } else { - if {[llength $value] == 0} { - set value 0 - } - } - if {[string compare -nocase $arg "C_MICRO_DMA"] == 0} { - if {[llength $value] == 0} { - set value 1 - } - } else { - if {[llength $value] == 0} { - set value 0 - } - } - } - - set value [xformat_addr_string $value $arg] - if {[string compare -nocase "HW_VER" $arg] == 0} { - puts $file_handle "#define [xget_name $periph $arg] \"$value\"" - } else { - puts $file_handle "#define [xget_name $periph $arg] $value" - } - } - puts $file_handle "" - } - puts $file_handle "\n/******************************************************************/\n" - close $file_handle -} - -#----------------------------------------------------------------------------- -# ::hsi::utils::define_canonical_xpars - Used to print out canonical defines for a driver. -# Given a list of arguments, define each as a canonical constant name, using -# the driver name, in an include file. -#----------------------------------------------------------------------------- -proc xdefine_axidma_canonical_xpars {drv_handle file_name drv_string args} { - # Open include file - set file_handle [xopen_include_file $file_name] - - # Get all the peripherals connected to this driver - set periphs [xget_sw_iplist_for_driver $drv_handle] - - # Get the names of all the peripherals connected to this driver - foreach periph $periphs { - set peripheral_name [string toupper [get_property NAME $periph]] - lappend peripherals $peripheral_name - } - - # Get possible canonical names for all the peripherals connected to this - # driver - set device_id 0 - foreach periph $periphs { - set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]] - lappend canonicals $canonical_name - - # Create a list of IDs of the peripherals whose hardware instance name - # doesn't match the canonical name. These IDs can be used later to - # generate canonical definitions - if { [lsearch $peripherals $canonical_name] < 0 } { - lappend indices $device_id - } - incr device_id - } - - set i 0 - foreach periph $periphs { - set periph_name [string toupper [get_property NAME $periph]] - - # Generate canonical definitions only for the peripherals whose - # canonical name is not the same as hardware instance name - if { [lsearch $canonicals $periph_name] < 0 } { - puts $file_handle "/* Canonical definitions for peripheral $periph_name */" - set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]] - - foreach arg $args { - set lvalue [xget_dname $canonical_name $arg] - # The commented out rvalue is the name of the instance-specific constant - # set rvalue [xget_name $periph $arg] - # The rvalue set below is the actual value of the parameter - set rvalue [xget_param_value $periph $arg] - - if {[string compare -nocase $arg "C_INCLUDE_SG"] == 0} { - if {[llength $rvalue] == 0} { - set rvalue 1 - } - } else { - if {[llength $rvalue] == 0} { - set rvalue 0 - } - } - if {[string compare -nocase $arg "C_MICRO_DMA"] == 0} { - if {[llength $rvalue] == 0} { - set rvalue 1 - } - } else { - if {[llength $rvalue] == 0} { - set rvalue 0 - } - } - set rvalue [xformat_addr_string $rvalue $arg] - - puts $file_handle "#define $lvalue $rvalue" - - } - puts $file_handle "" - incr i - } - } - - puts $file_handle "\n/******************************************************************/\n" - close $file_handle -} diff --git a/thirdparty/libxil/orig/axidma_v9_0/data/axidma_header.h b/thirdparty/libxil/orig/axidma_v9_0/data/axidma_header.h deleted file mode 100644 index fe4fab014..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/data/axidma_header.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* Use of the Software is limited solely to applications: -* (a) running on a Xilinx device, or -* (b) that interact with a Xilinx device through a bus or interconnect. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -* SOFTWARE. -* -* Except as contained in this notice, the name of the Xilinx shall not be used -* in advertising or otherwise to promote the sale, use or other dealings in -* this Software without prior written authorization from Xilinx. -* -******************************************************************************/ -#ifndef AXIDMA_HEADER_H /* prevent circular inclusions */ -#define AXIDMA_HEADER_H /* by using protection macros */ - -#include "xil_types.h" -#include "xil_assert.h" -#include "xstatus.h" - -int AxiDMASelfTestExample(u16 DeviceId); - -#endif diff --git a/thirdparty/libxil/orig/axidma_v9_0/data/axidma_tapp.tcl b/thirdparty/libxil/orig/axidma_v9_0/data/axidma_tapp.tcl deleted file mode 100644 index 865d9d319..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/data/axidma_tapp.tcl +++ /dev/null @@ -1,121 +0,0 @@ -############################################################################### -# -# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# Use of the Software is limited solely to applications: -# (a) running on a Xilinx device, or -# (b) that interact with a Xilinx device through a bus or interconnect. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -# Except as contained in this notice, the name of the Xilinx shall not be used -# in advertising or otherwise to promote the sale, use or other dealings in -# this Software without prior written authorization from Xilinx. -# -############################################################################## -# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl - -# ----------------------------------------------------------------- -# Software Project Types (swproj): -# 0 : MemoryTest - Calls basic memorytest routines from common driver dir -# 1 : PeripheralTest - Calls any existing polled_example and/or selftest -# ----------------------------------------------------------------- - -# ----------------------------------------------------------------- -# TCL Procedures: -# ----------------------------------------------------------------- - -proc gen_include_files {swproj mhsinst} { - if {$swproj == 0} { - return "" - } - if {$swproj == 1} { - set inc_file_lines {axidma_header.h} - return $inc_file_lines - } -} - -proc gen_src_files {swproj mhsinst} { - if {$swproj == 0} { - return "" - } - if {$swproj == 1} { - set inc_file_lines {examples/xaxidma_example_selftest.c data/axidma_header.h} - return $inc_file_lines - } -} - -proc gen_testfunc_def {swproj mhsinst} { - return "" -} - -proc gen_init_code {swproj mhsinst} { - return "" -} - -proc gen_testfunc_call {swproj mhsinst} { - - if {$swproj == 0} { - return "" - } - - set ipname [get_property NAME $mhsinst] - set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"] - set stdout [get_property CONFIG.STDOUT [get_os]] - if { $stdout == "" || $stdout == "none" } { - set hasStdout 0 - } else { - set hasStdout 1 - } - - set testfunc_call "" - - if {${hasStdout} == 0} { - - append testfunc_call " - - { - int status; - - status = AxiDMASelfTestExample(${deviceid}); - - }" - } else { - - append testfunc_call " - - { - int status; - - - print(\"\\r\\n Running AxiDMASelfTestExample() for ${ipname}...\\r\\n\"); - - status = AxiDMASelfTestExample(${deviceid}); - - if (status == 0) { - print(\"AxiDMASelfTestExample PASSED\\r\\n\"); - } - else { - print(\"AxiDMASelfTestExample FAILED\\r\\n\"); - } - }" - } - - return $testfunc_call -} diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/HTML_custom.css b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/HTML_custom.css deleted file mode 100644 index 26defe1a8..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/HTML_custom.css +++ /dev/null @@ -1,1430 +0,0 @@ -/* The standard CSS for doxygen 1.8.5 */ - -body{ - background: none repeat scroll 0 0 #FFFFFF; - color: #51626F; - font-family: arial,sans-serif !important; - font-size: 75% !important; - font-weight: normal !important; - margin-left: 10px; - font: 400 12px/15px arial,sans-serif; -} -.contents, .textblock { -font: 400 12px/15px arial,sans-serif; -} -.textblock ul, .contents ul{ - margin: 5px 0; - padding: 0; -} -.textblockol { - margin:5px 15px; - padding:0; - list-style-image: none; -} -.textblock li, .contents li { - margin: 0 0 2px 15px; - padding: 0 0 2px 2px; -} - -/* For hiding RHS TOC -.toc{ -display:none; -}*/ -/* For hiding RHS TOC*/ - -For hiding Nav Bar -.navpath, #nav-path{ -display:none; -} -/* For hiding Nav Bar*/ -/* For hiding extra navrows */ -#navrow2, #navrow3, #navrow4, #navrow5 { -display:none; -} -/* @group Heading Levels */ - -.title { - font: 400 14px/28px arial,sans-serif; - font-size: 150%; - font-weight: bold; - margin: 9px 2px; - text-align: left; -} - -h2, h3 { - color: #E66A08 !important; - font-size: 1.2em !important; - line-height: 1.2em !important; - text-indent: 0 !important; -} -h4, h5{ - color: #E66A08 !important; - font-size: 1.2em !important; - line-height: 1.2em !important; -} -h5{ - font-size: 1.0em !important; - line-height: 1.0em !important; -} -h6{ - color: #E66A08 !important; - font-size: 1.0em !important; - line-height: 1.0em !important; -} -p { - padding-bottom: 0px !important; - font: 400 12px/15px arial,sans-serif; -} -li p { - padding-bottom: 0px !important; - margin: 0px; -} - -h1, h2.groupheader { - clear: both !important; - color: #627178 !important; - font-size: 1.4em !important; - font-weight: bold !important; - line-height: 28px !important; - margin-top: 0.6em !important; -} - -h1, h2, h3, h4, h5, h6 { - -webkit-transition: text-shadow 0.5s linear; - -moz-transition: text-shadow 0.5s linear; - -ms-transition: text-shadow 0.5s linear; - -o-transition: text-shadow 0.5s linear; - transition: text-shadow 0.5s linear; - margin-right: 15px; -} - -h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { - text-shadow: 0 0 15px cyan; -} - -dt { - font-weight: bold; -} - - -/*Hiding Tabs - Tushar -div.tabs -{ - visibility: hidden; -} */ - -div.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; -} - -p.startli, p.startdd, p.starttd { - margin-top: 2px; -} - -p.endli { - margin-bottom: 0px; -} - -p.enddd { - margin-bottom: 4px; -} - -p.endtd { - margin-bottom: 2px; -} - -/* @end */ - -caption { - font-weight: bold; -} - -span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex, div.navtab{ - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; -} - -div.qindex, div.navpath { - width: 100%; - line-height: 140%; -} - -div.navtab { - margin-right: 15px; -} - -/* @group Link Styling */ - -a { - color: #017bba; - font-weight: normal; - text-decoration: none; - /*font: 400 12px/15px;*/ -} - -.contents a:visited { - color: #4665A2; -} - -a:hover { - text-decoration: underline; -} - -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #9CAFD4; - color: #ffffff; - border: 1px double #869DCA; -} - -.contents a.qindexHL:visited { - color: #ffffff; -} - -a.el { - font-weight: bold; -} - -a.elRef { -} - -a.code, a.code:visited, a.line, a.line:visited { - color: #4665A2; -} - -a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { - color: #4665A2; - /*font: 400 12px/15px;*/ -} - -/* @end */ - -dl.el { - margin-left: -1cm; -} - -pre.fragment { - border: 0px solid #C4CFE5; - background-color: #FFFFFF; - padding: 4px 6px; - margin: 4px 8px 4px 2px; - overflow: auto; - word-wrap: break-word; - font-size: 9pt; - line-height: 125%; - font-family: monospace, fixed; - font-size: 105%; -} - -div.fragment { - padding: 0px; - margin: 0px; - background-color: #FFFFFF; - border: 0px solid #C4CFE5; -} - -div.line { - font-family: monospace, fixed; - font-size: 13px; - min-height: 13px; - line-height: 1.0; - text-wrap: unrestricted; - white-space: -moz-pre-wrap; /* Moz */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - white-space: pre-wrap; /* CSS3 */ - word-wrap: break-word; /* IE 5.5+ */ - text-indent: -53px; - padding-left: 53px; - padding-bottom: 0px; - margin: 0px; - -webkit-transition-property: background-color, box-shadow; - -webkit-transition-duration: 0.5s; - -moz-transition-property: background-color, box-shadow; - -moz-transition-duration: 0.5s; - -ms-transition-property: background-color, box-shadow; - -ms-transition-duration: 0.5s; - -o-transition-property: background-color, box-shadow; - -o-transition-duration: 0.5s; - transition-property: background-color, box-shadow; - transition-duration: 0.5s; -} - -div.line.glow { - background-color: cyan; - box-shadow: 0 0 10px cyan; -} - - -span.lineno { - padding-right: 4px; - text-align: right; - border-right: 2px solid #0F0; - background-color: #E8E8E8; - white-space: pre; -} -span.lineno a { - background-color: #D8D8D8; -} - -span.lineno a:hover { - background-color: #C8C8C8; -} - -div.ah { - background-color: black; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px; - padding: 0.2em; - border: solid thin #333; - border-radius: 0.5em; - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - box-shadow: 2px 2px 3px #999; - -webkit-box-shadow: 2px 2px 3px #999; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); - background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); -} - -div.groupHeader { - margin-left: 16px; - margin-top: 12px; - font-weight: bold; -} - -div.groupText { - margin-left: 16px; - font-style: italic; -} - -body { - background-color: white; - margin: 0; -} - -div.contents { - margin-top: 10px; - margin-left: 12px; - margin-right: 8px; -} - -td.indexkey { - background-color: #EBEFF6; - font-weight: bold; - border: 1px solid #C4CFE5; - margin: 2px 0px 2px 0; - padding: 2px 10px; - white-space: nowrap; - vertical-align: top; -} - -td.indexvalue { - background-color: #EBEFF6; - border: 1px solid #C4CFE5; - padding: 2px 10px; - margin: 2px 0px; -} - -tr.memlist { - background-color: #EEF1F7; -} - -p.formulaDsp { - text-align: center; -} - -img.formulaDsp { - -} - -img.formulaInl { - vertical-align: middle; -} - -div.center { - text-align: center; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; -} - -div.center img { - border: 0px; -} - -address.footer { - text-align: right; - padding-right: 12px; -} - -img.footer { - border: 0px; - vertical-align: middle; -} - -/* @group Code Colorization */ - -span.keyword { - color: #008000 -} - -span.keywordtype { - color: #604020 -} - -span.keywordflow { - color: #e08000 -} - -span.comment { - color: #51626F -} - -span.preprocessor { - color: #806020 -} - -span.stringliteral { - color: #002080 -} - -span.charliteral { - color: #008080 -} - -span.vhdldigit { - color: #ff00ff -} - -span.vhdlchar { - color: #000000 -} - -span.vhdlkeyword { - color: #700070 -} - -span.vhdllogic { - color: #ff0000 -} - -blockquote { - background-color: #F7F8FB; - border-left: 2px solid #9CAFD4; - margin: 0 24px 0 4px; - padding: 0 12px 0 16px; -} - -/* @end */ - -/* -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} -*/ - -td.tiny { - font-size: 75%; -} - -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #A3B4D7; -} - -th.dirtab { - background: #EBEFF6; - font-weight: bold; -} - -hr { - height: 0px; - border: none; - border-top: 1px solid #4A6AAA; -} - -hr.footer { - height: 1px; -} - -/* @group Member Descriptions */ - -table.memberdecls { - border-spacing: 0px; - padding: 0px; -} - -.memberdecls td, .fieldtable tr { - -webkit-transition-property: background-color, box-shadow; - -webkit-transition-duration: 0.5s; - -moz-transition-property: background-color, box-shadow; - -moz-transition-duration: 0.5s; - -ms-transition-property: background-color, box-shadow; - -ms-transition-duration: 0.5s; - -o-transition-property: background-color, box-shadow; - -o-transition-duration: 0.5s; - transition-property: background-color, box-shadow; - transition-duration: 0.5s; -} - -.memberdecls td.glow, .fieldtable tr.glow { - background-color: cyan; - box-shadow: 0 0 15px cyan; -} - -.mdescLeft, .mdescRight, -.memItemLeft, .memItemRight, -.memTemplItemLeft, .memTemplItemRight, .memTemplParams { - background-color: #F9FAFC; - border: none; - margin: 4px; - padding: 1px 0 0 8px; -} - -.mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - color: #555; -} - -.memSeparator { - border-bottom: 1px solid #DEE4F0; - line-height: 1px; - margin: 0px; - padding: 0px; -} - -.memItemLeft, .memTemplItemLeft { - white-space: nowrap; -} - -.memItemRight { - width: 100%; -} - -.memTemplParams { - color: #4665A2; - white-space: nowrap; - font-size: 80%; -} - -/* @end */ - -/* @group Member Details */ - -/* Styles for detailed member documentation */ - -.memtemplate { - font-size: 80%; - color: #4665A2; - font-weight: normal; - margin-left: 9px; -} - -.memnav { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - -.mempage { - width: 100%; -} - -.memitem { - padding: 0; - margin-bottom: 10px; - margin-right: 5px; - -webkit-transition: box-shadow 0.5s linear; - -moz-transition: box-shadow 0.5s linear; - -ms-transition: box-shadow 0.5s linear; - -o-transition: box-shadow 0.5s linear; - transition: box-shadow 0.5s linear; - display: table !important; - width: 100%; -} - -.memitem.glow { - box-shadow: 0 0 15px cyan; -} - -.memname { - font-weight: bold; - margin-left: 6px; -} - -.memname td { - vertical-align: bottom; -} - -.memproto, dl.reflist dt { - border-top: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - padding: 6px 0px 6px 0px; - color: #E66A08 !important; - font-weight: bold; - text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - background-image:url('nav_f.png'); - background-repeat:repeat-x; - background-color: #E2E8F2; - /* opera specific markup */ - box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - border-top-right-radius: 4px; - border-top-left-radius: 4px; - /* firefox specific markup */ - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 4px; - -moz-border-radius-topleft: 4px; - /* webkit specific markup */ - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - -} - -.memdoc, dl.reflist dd { - border-bottom: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - padding: 6px 10px 2px 10px; - background-color: #FBFCFD; - border-top-width: 0; - background-image:url('nav_g.png'); - background-repeat:repeat-x; - background-color: #FFFFFF; - /* opera specific markup */ - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - /* firefox specific markup */ - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-bottomright: 4px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - /* webkit specific markup */ - -webkit-border-bottom-left-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -} - -dl.reflist dt { - padding: 5px; -} - -dl.reflist dd { - margin: 0px 0px 10px 0px; - padding: 5px; -} - -.paramkey { - text-align: right; -} - -.paramtype { - white-space: nowrap; -} - -.paramname { - color: #602020; - white-space: nowrap; -} -.paramname em { - font-style: normal; -} -.paramname code { - line-height: 14px; -} - -.params, .retval, .exception, .tparams { - margin-left: 0px; - padding-left: 0px; - font: 400 12px/15px arial,sans-serif; -} - -.params .paramname, .retval .paramname { - font-weight: bold; - vertical-align: top; -} - -.params .paramtype { - font-style: italic; - vertical-align: top; -} - -.params .paramdir { - font-family: "courier new",courier,monospace; - vertical-align: top; -} - -table.mlabels { - border-spacing: 0px; -} - -td.mlabels-left { - width: 100%; - padding: 0px; -} - -td.mlabels-right { - vertical-align: bottom; - padding: 0px; - white-space: nowrap; -} - -span.mlabels { - margin-left: 8px; -} - -span.mlabel { - background-color: #728DC1; - border-top:1px solid #5373B4; - border-left:1px solid #5373B4; - border-right:1px solid #C4CFE5; - border-bottom:1px solid #C4CFE5; - text-shadow: none; - color: white; - margin-right: 4px; - padding: 2px 3px; - border-radius: 3px; - font-size: 7pt; - white-space: nowrap; - vertical-align: middle; -} - - - -/* @end */ - -/* these are for tree view when not used as main index */ - -div.directory { - margin: 10px 0px; - border-top: 1px solid #A8B8D9; - border-bottom: 1px solid #A8B8D9; - width: 100%; -} - -.directory table { - border-collapse:collapse; -} - -.directory td { - margin: 0px; - padding: 0px; - vertical-align: top; -} - -.directory td.entry { - white-space: nowrap; - padding-right: 6px; - padding-top: 3px; -} - -.directory td.entry a { - outline:none; -} - -.directory td.entry a img { - border: none; -} - -.directory td.desc { - width: 100%; - padding-left: 6px; - padding-right: 6px; - padding-top: 3px; - border-left: 1px solid rgba(0,0,0,0.05); -} - -.directory tr.even { - padding-left: 6px; - background-color: #F7F8FB; -} - -.directory img { - vertical-align: -30%; -} - -.directory .levels { - white-space: nowrap; - width: 100%; - text-align: right; - font-size: 9pt; -} - -.directory .levels span { - cursor: pointer; - padding-left: 2px; - padding-right: 2px; - color: #3D578C; -} - -div.dynheader { - margin-top: 8px; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -address { - font-style: normal; - color: #2A3D61; -} - -table.doxtable { - border-collapse:collapse; - margin-top: 4px; - margin-bottom: 4px; - font: 400 12px/15px arial,sans-serif; -} - -table.doxtable td, table.doxtable th { - border: 1px solid #2D4068; - padding: 3px 7px 2px; -} - -table.doxtable th { - background-color: #CCCCCC; - color: #51626F; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; -} -table.fieldtable { - /*width: 100%;*/ - margin-bottom: 10px; - border: 1px solid #A8B8D9; - border-spacing: 0px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); -} - -.fieldtable td, .fieldtable th { - padding: 3px 7px 2px; -} - -.fieldtable td.fieldtype, .fieldtable td.fieldname { - white-space: nowrap; - border-right: 1px solid #A8B8D9; - border-bottom: 1px solid #A8B8D9; - vertical-align: top; -} - -.fieldtable td.fieldname { - padding-top: 3px; -} - -.fieldtable td.fielddoc { - border-bottom: 1px solid #A8B8D9; - /*width: 100%;*/ -} - -.fieldtable td.fielddoc p:first-child { - margin-top: 0px; -} - -.fieldtable td.fielddoc p:last-child { - margin-bottom: 2px; -} - -.fieldtable tr:last-child td { - border-bottom: none; -} - -.fieldtable th { - background-image:url('nav_f.png'); - background-repeat:repeat-x; - background-color: #E2E8F2; - font-size: 90%; - color: #253555; - padding-bottom: 4px; - padding-top: 5px; - text-align:left; - -moz-border-radius-topleft: 4px; - -moz-border-radius-topright: 4px; - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom: 1px solid #A8B8D9; -} - - -.tabsearch { - top: 5px; - left: 10px; - height: 36px; - background-image: url('tab_b.png'); - z-index: 101; - overflow: hidden; - font-size: 13px; -} - -.navpath ul -{ - font-size: 11px; - background-image:url('tab_b.png'); - background-repeat:repeat-x; - background-position: 0 -5px; - height:30px; - line-height:30px; - color:#8AA0CC; - border:solid 1px #C2CDE4; - overflow:hidden; - margin:0px; - padding:0px; -} - -.navpath li -{ - list-style-type:none; - float:left; - padding-left:10px; - padding-right:15px; - background-image:url('bc_s.png'); - background-repeat:no-repeat; - background-position:right; - color:#364D7C; -} - -.navpath li.navelem a -{ - height:32px; - display:block; - text-decoration: none; - outline: none; - color: #283A5D; - font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; - text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - text-decoration: none; -} - -.navpath li.navelem a:hover -{ - color:#6884BD; -} - -.navpath li.footer -{ - list-style-type:none; - float:right; - padding-left:10px; - padding-right:15px; - background-image:none; - background-repeat:no-repeat; - background-position:right; - color:#364D7C; - font-size: 8pt; -} - - -div.summary -{ - float: right; - font-size: 8pt; - padding-right: 5px; - width: 50%; - text-align: right; -} - -div.summary a -{ - white-space: nowrap; -} - -div.ingroups -{ - font-size: 8pt; - width: 50%; - text-align: left; -} - -div.ingroups a -{ - white-space: nowrap; -} - -div.header -{ - background-image:url(''); - background-repeat:repeat-x; - background-color: #FFFFFF; - margin: 0px; - border-bottom: 0px solid #C4CFE5; -} - -div.headertitle -{ - padding: 5px 5px 5px 10px; -} - -dl -{ - padding: 0 0 0 10px; - font: 400 12px/15px arial,sans-serif; -} - -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ -dl.section -{ - margin-left: 0px; - padding-left: 0px; -} - -dl.note -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #D0C000; -} - -dl.warning, dl.attention -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #FF0000; -} - -dl.pre, dl.post, dl.invariant -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00D000; -} - -dl.deprecated -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #505050; -} - -dl.todo -{ - margin-left:-7px; - padding-left: 12px; - border-left:4px solid; - border-color: #00C0E0; -} - -dl.test -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #3030E0; -} - -dl.bug -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #C08050; -} - -dl.section dd { - margin-bottom: 6px; -} - - -#projectlogo -{ - text-align: center; - vertical-align: bottom; - border-collapse: separate; - padding: 12px; - -} - -#projectlogo img -{ - border: 0px none; -} - -#projectname -{ - font: 300% Tahoma, Arial,sans-serif; - margin: 0px; - padding: 5px 0px; - text-align: right; - width: 100%; -} - -#projectbrief -{ - font: 120% Tahoma, Arial,sans-serif; - margin: 0px; - padding: 5px; - text-align: left; - width: 100%; -} - -#projectnumber -{ - font: 50% Tahoma, Arial,sans-serif; - margin: 0px; - padding: 0px; -} - -#titlearea -{ - padding: 0px; - margin: 0px; - width: 100%; - border-bottom: 11px solid #5373B4; -} - -.image -{ - text-align: left; -} - -.dotgraph -{ - text-align: center; -} - -.mscgraph -{ - text-align: center; -} - -.caption -{ - font-weight: bold; -} - -div.zoom -{ - border: 1px solid #90A5CE; -} - -dl.citelist { - margin-bottom:50px; -} - -dl.citelist dt { - color:#334975; - float:left; - font-weight:bold; - margin-right:10px; - padding:5px; -} - -dl.citelist dd { - margin:2px 0; - padding:5px 0; -} - -div.toc { - padding: 14px 25px; - background-color: #F4F6FA; - border: 1px solid #D8DFEE; - border-radius: 7px 7px 7px 7px; - float: right; - height: auto; - margin: 0 20px 10px 10px; - width: 200px; -} - -div.toc li { - background: url("bdwn.png") no-repeat scroll 0 5px transparent; - font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; - margin-top: 5px; - padding-left: 10px; - padding-top: 2px; -} - -div.toc h3 { - font: bold 12px/1.2 Arial,FreeSans,sans-serif; - color: #4665A2; - border-bottom: 0 none; - margin: 0; -} - -div.toc ul { - list-style: none outside none; - border: medium none; - padding: 0px; -} - -div.toc li.level1 { - margin-left: 0px; -} - -div.toc li.level2 { - margin-left: 15px; -} - -div.toc li.level3 { - margin-left: 30px; -} - -div.toc li.level4 { - margin-left: 45px; -} - -.inherit_header { - font-weight: bold; - color: gray; - cursor: pointer; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.inherit_header td { - padding: 6px 0px 2px 5px; -} - -.inherit { - display: none; -} - -tr.heading h2 { - margin-top: 12px; - margin-bottom: 4px; -} - -/* tooltip related style info */ - -.ttc { - position: absolute; - display: none; -} - -#powerTip { - cursor: default; - white-space: nowrap; - background-color: white; - border: 1px solid gray; - border-radius: 4px 4px 4px 4px; - box-shadow: 1px 1px 7px gray; - display: none; - font-size: smaller; - max-width: 80%; - opacity: 0.9; - padding: 1ex 1em 1em; - position: absolute; - z-index: 2147483647; -} - -#powerTip div.ttdoc { - color: grey; - font-style: italic; -} - -#powerTip div.ttname a { - font-weight: bold; -} - -#powerTip div.ttname { - font-weight: bold; -} - -#powerTip div.ttdeci { - color: #006318; -} - -#powerTip div { - margin: 0px; - padding: 0px; - font: 12px/16px arial,sans-serif; -} - -#powerTip:before, #powerTip:after { - content: ""; - position: absolute; - margin: 0px; -} - -#powerTip.n:after, #powerTip.n:before, -#powerTip.s:after, #powerTip.s:before, -#powerTip.w:after, #powerTip.w:before, -#powerTip.e:after, #powerTip.e:before, -#powerTip.ne:after, #powerTip.ne:before, -#powerTip.se:after, #powerTip.se:before, -#powerTip.nw:after, #powerTip.nw:before, -#powerTip.sw:after, #powerTip.sw:before { - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; -} - -#powerTip.n:after, #powerTip.s:after, -#powerTip.w:after, #powerTip.e:after, -#powerTip.nw:after, #powerTip.ne:after, -#powerTip.sw:after, #powerTip.se:after { - border-color: rgba(255, 255, 255, 0); -} - -#powerTip.n:before, #powerTip.s:before, -#powerTip.w:before, #powerTip.e:before, -#powerTip.nw:before, #powerTip.ne:before, -#powerTip.sw:before, #powerTip.se:before { - border-color: rgba(128, 128, 128, 0); -} - -#powerTip.n:after, #powerTip.n:before, -#powerTip.ne:after, #powerTip.ne:before, -#powerTip.nw:after, #powerTip.nw:before { - top: 100%; -} - -#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #ffffff; - border-width: 10px; - margin: 0px -10px; -} -#powerTip.n:before { - border-top-color: #808080; - border-width: 11px; - margin: 0px -11px; -} -#powerTip.n:after, #powerTip.n:before { - left: 50%; -} - -#powerTip.nw:after, #powerTip.nw:before { - right: 14px; -} - -#powerTip.ne:after, #powerTip.ne:before { - left: 14px; -} - -#powerTip.s:after, #powerTip.s:before, -#powerTip.se:after, #powerTip.se:before, -#powerTip.sw:after, #powerTip.sw:before { - bottom: 100%; -} - -#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #ffffff; - border-width: 10px; - margin: 0px -10px; -} - -#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { - border-bottom-color: #808080; - border-width: 11px; - margin: 0px -11px; -} - -#powerTip.s:after, #powerTip.s:before { - left: 50%; -} - -#powerTip.sw:after, #powerTip.sw:before { - right: 14px; -} - -#powerTip.se:after, #powerTip.se:before { - left: 14px; -} - -#powerTip.e:after, #powerTip.e:before { - left: 100%; -} -#powerTip.e:after { - border-left-color: #ffffff; - border-width: 10px; - top: 50%; - margin-top: -10px; -} -#powerTip.e:before { - border-left-color: #808080; - border-width: 11px; - top: 50%; - margin-top: -11px; -} - -#powerTip.w:after, #powerTip.w:before { - right: 100%; -} -#powerTip.w:after { - border-right-color: #ffffff; - border-width: 10px; - top: 50%; - margin-top: -10px; -} -#powerTip.w:before { - border-right-color: #808080; - border-width: 11px; - top: 50%; - margin-top: -11px; -} - -@media print -{ - #top { display: none; } - #side-nav { display: none; } - #nav-path { display: none; } - body { overflow:visible; } - h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } - .summary { display: none; } - .memitem { page-break-inside: avoid; } - #doc-content - { - margin-left:0 !important; - height:auto !important; - width:auto !important; - overflow:inherit; - display:inline; - } -} - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/annotated.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/annotated.html deleted file mode 100644 index 7c33a3a71..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/annotated.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - -axidma_v9_0: Data Structures - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - -
-
-
-
Data Structures
-
-
-
Here are the data structures with brief descriptions:
- - - - -
 CXAxiDmaThe XAxiDma driver instance data
 CXAxiDma_BdRingContainer structure for descriptor storage control
 CXAxiDma_ConfigThe configuration structure for AXI DMA engine
-
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/classes.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/classes.html deleted file mode 100644 index 06bd550cc..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/classes.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - -axidma_v9_0: Data Structure Index - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - -
-
-
-
Data Structure Index
-
-
- - - - - - -
  X  
-
XAxiDma_BdRing   XAxiDma_Config   
XAxiDma   
- -
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/doc.png b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/doc.png deleted file mode 100644 index 17edabff95f7b8da13c9516a04efe05493c29501..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/dynsections.js b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/dynsections.js deleted file mode 100644 index 85e183690..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/dynsections.js +++ /dev/null @@ -1,97 +0,0 @@ -function toggleVisibility(linkObj) -{ - var base = $(linkObj).attr('id'); - var summary = $('#'+base+'-summary'); - var content = $('#'+base+'-content'); - var trigger = $('#'+base+'-trigger'); - var src=$(trigger).attr('src'); - if (content.is(':visible')===true) { - content.hide(); - summary.show(); - $(linkObj).addClass('closed').removeClass('opened'); - $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); - } else { - content.show(); - summary.hide(); - $(linkObj).removeClass('closed').addClass('opened'); - $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); - } - return false; -} - -function updateStripes() -{ - $('table.directory tr'). - removeClass('even').filter(':visible:even').addClass('even'); -} - -function toggleLevel(level) -{ - $('table.directory tr').each(function() { - var l = this.id.split('_').length-1; - var i = $('#img'+this.id.substring(3)); - var a = $('#arr'+this.id.substring(3)); - if (l - - - - - -axidma_v9_0: File List - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - -
-
-
-
File List
-
-
-
Here is a list of all documented files with brief descriptions:
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions.html deleted file mode 100644 index 0bd7ad51e..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - -axidma_v9_0: Data Fields - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - - -
-
-
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions_vars.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions_vars.html deleted file mode 100644 index ea2952237..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/functions_vars.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - -axidma_v9_0: Data Fields - Variables - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - - -
-
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals.html deleted file mode 100644 index 10e1f1c51..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals.html +++ /dev/null @@ -1,558 +0,0 @@ - - - - - - -axidma_v9_0: APIs - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - - -
-
-
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
- -

- x -

-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_defs.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_defs.html deleted file mode 100644 index dc4b4eaec..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_defs.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - -axidma_v9_0: APIs - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - - -
-
-  - -

- x -

-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_func.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_func.html deleted file mode 100644 index 7e0916d17..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_func.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - -axidma_v9_0: APIs - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - - -
-
-  - -

- x -

-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_type.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_type.html deleted file mode 100644 index b55476cd0..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/globals_type.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - -axidma_v9_0: APIs - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - - -
-
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/group__axidma__v9__0.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/group__axidma__v9__0.html deleted file mode 100644 index a8d41e072..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/group__axidma__v9__0.html +++ /dev/null @@ -1,5350 +0,0 @@ - - - - - - -axidma_v9_0: Axidma_v9_0 - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - -
-
- -
-
Axidma_v9_0
-
-
- - - - - - - - -

-Data Structures

struct  XAxiDma
 
struct  XAxiDma_Config
 
struct  XAxiDma_BdRing
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-Macros

#define XAxiDma_GetTxRing(InstancePtr)   (&((InstancePtr)->TxBdRing))
 
#define XAxiDma_GetRxRing(InstancePtr)   (&((InstancePtr)->RxBdRing[0]))
 
#define XAxiDma_GetRxIndexRing(InstancePtr, RingIndex)   (&((InstancePtr)->RxBdRing[RingIndex]))
 
#define XAxiDma_HasSg(InstancePtr)   ((InstancePtr)->HasSg) ? TRUE : FALSE
 
#define XAxiDma_IntrEnable(InstancePtr, Mask, Direction)
 
#define XAxiDma_IntrGetEnabled(InstancePtr, Direction)
 
#define XAxiDma_IntrDisable(InstancePtr, Mask, Direction)
 
#define XAxiDma_IntrGetIrq(InstancePtr, Direction)
 
#define XAxiDma_IntrAckIrq(InstancePtr, Mask, Direction)
 
#define XAxiDma_BdRead(BaseAddress, Offset)   (*(u32 *)((UINTPTR)((void *)(BaseAddress)) + (u32)(Offset)))
 
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)   (*(u32 *)((UINTPTR)(void *)(BaseAddress) + (u32)(Offset))) = (u32)(Data)
 
#define XAxiDma_BdClear(BdPtr)
 
#define XAxiDma_BdGetCtrl(BdPtr)
 
#define XAxiDma_BdGetSts(BdPtr)
 
#define XAxiDma_BdGetLength(BdPtr, LengthMask)
 
#define XAxiDma_BdSetId(BdPtr, Id)    (XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_ID_OFFSET, (u32)(Id)))
 
#define XAxiDma_BdGetId(BdPtr)   (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_ID_OFFSET))
 
#define XAxiDma_BdGetBufAddr(BdPtr)    (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_BUFA_OFFSET))
 
#define XAxiDma_BdHwCompleted(BdPtr)
 
#define XAxiDma_BdGetActualLength(BdPtr, LengthMask)
 
#define XAxiDma_BdSetTId(BdPtr, TId)
 
#define XAxiDma_BdGetTId(BdPtr)
 
#define XAxiDma_BdSetTDest(BdPtr, TDest)
 
#define XAxiDma_BdGetTDest(BdPtr)
 
#define XAxiDma_BdSetTUser(BdPtr, TUser)
 
#define XAxiDma_BdGetTUser(BdPtr)
 
#define XAxiDma_BdSetARCache(BdPtr, ARCache)
 
#define XAxiDma_BdGetARCache(BdPtr)
 
#define XAxiDma_BdSetARUser(BdPtr, ARUser)
 
#define XAxiDma_BdGetARUser(BdPtr)
 
#define XAxiDma_BdSetStride(BdPtr, Stride)
 
#define XAxiDma_BdGetStride(BdPtr)
 
#define XAxiDma_BdSetVSize(BdPtr, VSize)
 
#define XAxiDma_BdGetVSize(BdPtr)
 
#define XAxiDma_BdRingCntCalc(Alignment, Bytes)    (uint32_t)((Bytes)/((sizeof(XAxiDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
 
#define XAxiDma_BdRingMemCalc(Alignment, NumBd)   (int)((sizeof(XAxiDma_Bd)+((Alignment)-1)) & ~((Alignment)-1))*(NumBd)
 
#define XAxiDma_BdRingGetCnt(RingPtr)   ((RingPtr)->AllCnt)
 
#define XAxiDma_BdRingGetFreeCnt(RingPtr)   ((RingPtr)->FreeCnt)
 
#define XAxiDma_BdRingSnapShotCurrBd(RingPtr)
 
#define XAxiDma_BdRingGetCurrBd(RingPtr)
 
#define XAxiDma_BdRingNext(RingPtr, BdPtr)
 
#define XAxiDma_BdRingPrev(RingPtr, BdPtr)
 
#define XAxiDma_BdRingGetSr(RingPtr)   XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET)
 
#define XAxiDma_BdRingGetError(RingPtr)
 
#define XAxiDma_BdRingHwIsStarted(RingPtr)
 
#define XAxiDma_BdRingBusy(RingPtr)
 
#define XAxiDma_BdRingIntEnable(RingPtr, Mask)
 
#define XAxiDma_BdRingIntGetEnabled(RingPtr)
 
#define XAxiDma_BdRingIntDisable(RingPtr, Mask)
 
#define XAxiDma_BdRingGetIrq(RingPtr)
 
#define XAxiDma_BdRingAckIrq(RingPtr, Mask)
 
- - - -

-Typedefs

typedef struct XAxiDma XAxiDma
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-Functions

int XAxiDma_CfgInitialize (XAxiDma *InstancePtr, XAxiDma_Config *Config)
 
void XAxiDma_Reset (XAxiDma *InstancePtr)
 
int XAxiDma_ResetIsDone (XAxiDma *InstancePtr)
 
int XAxiDma_Pause (XAxiDma *InstancePtr)
 
int XAxiDma_Resume (XAxiDma *InstancePtr)
 
u32 XAxiDma_Busy (XAxiDma *InstancePtr, int Direction)
 
int XAxiDma_SelectKeyHole (XAxiDma *InstancePtr, int Direction, int Select)
 
int XAxiDma_SelectCyclicMode (XAxiDma *InstancePtr, int Direction, int Select)
 
u32 XAxiDma_SimpleTransfer (XAxiDma *InstancePtr, UINTPTR BuffAddr, u32 Length, int Direction)
 
XAxiDma_ConfigXAxiDma_LookupConfig (u32 DeviceId)
 
int XAxiDma_Selftest (XAxiDma *InstancePtr)
 
int XAxiDma_BdSetLength (XAxiDma_Bd *BdPtr, u32 LenBytes, u32 LengthMask)
 
u32 XAxiDma_BdSetBufAddr (XAxiDma_Bd *BdPtr, UINTPTR Addr)
 
u32 XAxiDma_BdSetBufAddrMicroMode (XAxiDma_Bd *BdPtr, UINTPTR Addr)
 
int XAxiDma_BdSetAppWord (XAxiDma_Bd *BdPtr, int Offset, u32 Word)
 
u32 XAxiDma_BdGetAppWord (XAxiDma_Bd *BdPtr, int Offset, int *Valid)
 
void XAxiDma_BdSetCtrl (XAxiDma_Bd *BdPtr, u32 Data)
 
void XAxiDma_DumpBd (XAxiDma_Bd *BdPtr)
 
int XAxiDma_UpdateBdRingCDesc (XAxiDma_BdRing *RingPtr)
 
u32 XAxiDma_BdRingCreate (XAxiDma_BdRing *RingPtr, UINTPTR PhysAddr, UINTPTR VirtAddr, u32 Alignment, int BdCount)
 
int XAxiDma_BdRingClone (XAxiDma_BdRing *RingPtr, XAxiDma_Bd *SrcBdPtr)
 
int XAxiDma_StartBdRingHw (XAxiDma_BdRing *RingPtr)
 
int XAxiDma_BdRingStart (XAxiDma_BdRing *RingPtr)
 
int XAxiDma_BdRingSetCoalesce (XAxiDma_BdRing *RingPtr, u32 Counter, u32 Timer)
 
void XAxiDma_BdRingGetCoalesce (XAxiDma_BdRing *RingPtr, u32 *CounterPtr, u32 *TimerPtr)
 
int XAxiDma_BdRingAlloc (XAxiDma_BdRing *RingPtr, int NumBd, XAxiDma_Bd **BdSetPtr)
 
int XAxiDma_BdRingUnAlloc (XAxiDma_BdRing *RingPtr, int NumBd, XAxiDma_Bd *BdSetPtr)
 
int XAxiDma_BdRingToHw (XAxiDma_BdRing *RingPtr, int NumBd, XAxiDma_Bd *BdSetPtr)
 
int XAxiDma_BdRingFromHw (XAxiDma_BdRing *RingPtr, int BdLimit, XAxiDma_Bd **BdSetPtr)
 
int XAxiDma_BdRingFree (XAxiDma_BdRing *RingPtr, int NumBd, XAxiDma_Bd *BdSetPtr)
 
int XAxiDma_BdRingCheck (XAxiDma_BdRing *RingPtr)
 
void XAxiDma_BdRingDumpRegs (XAxiDma_BdRing *RingPtr)
 
- - - - -

-Device registers

Register sets on TX and RX channels are identical

-
#define XAXIDMA_RX_CDESC0_OFFSET   0x00000040
 
- - - - - -

-Bitmasks and shift values for XAXIDMA_BD_STRIDE_VSIZE_OFFSET register

#define XAxiDma_ReadReg(BaseAddress, RegOffset)    XAxiDma_In32((BaseAddress) + (RegOffset))
 
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)    XAxiDma_Out32((BaseAddress) + (RegOffset), (Data))
 
-

Macro Definition Documentation

- -
-
- - - - -
#define XAXIDMA_BD_ADDRLEN_OFFSET   0x40
-
- -

#include <xaxidma_hw.h>

- -

Check for BD Addr.

- -

Referenced by XAxiDma_BdRingCreate(), XAxiDma_BdSetBufAddr(), and XAxiDma_BdSetBufAddrMicroMode().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_BUFA_MSB_OFFSET   0x0C
-
- -

#include <xaxidma_hw.h>

- -

Buffer address.

- -

Referenced by XAxiDma_BdSetBufAddr(), and XAxiDma_BdSetBufAddrMicroMode().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_BUFA_OFFSET   0x08
-
- -

#include <xaxidma_hw.h>

- -

Buffer address.

- -

Referenced by XAxiDma_BdSetBufAddr(), XAxiDma_BdSetBufAddrMicroMode(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_BYTES_TO_CLEAR   48
-
- -

#include <xaxidma_hw.h>

- -

BD specific bytes to be cleared.

- -

Referenced by XAxiDma_BdRingClone().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_CTRL_ALL_MASK   0x0C000000
-
- -

#include <xaxidma_hw.h>

- -

All control bits.

- -

Referenced by XAxiDma_BdSetCtrl().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_CTRL_LEN_OFFSET   0x18
-
- -

#include <xaxidma_hw.h>

- -

Control/buffer length.

- -

Referenced by XAxiDma_BdRingFromHw(), XAxiDma_BdRingToHw(), XAxiDma_BdSetCtrl(), XAxiDma_BdSetLength(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_CTRL_TXEOF_MASK   0x04000000
-
- -

#include <xaxidma_hw.h>

- -

Last tx packet.

- -

Referenced by XAxiDma_BdRingFromHw(), and XAxiDma_BdRingToHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_CTRL_TXSOF_MASK   0x08000000
-
- -

#include <xaxidma_hw.h>

- -

First tx packet.

- -

Referenced by XAxiDma_BdRingToHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_HAS_DRE_MASK   0xF00
-
- -

#include <xaxidma_hw.h>

- -

Whether has DRE mask.

- -

Referenced by XAxiDma_BdSetBufAddr().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_HAS_DRE_OFFSET   0x3C
-
- -

#include <xaxidma_hw.h>

- -

Whether has DRE.

- -

Referenced by XAxiDma_BdRingCreate(), XAxiDma_BdSetBufAddr(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_HAS_DRE_SHIFT   8
-
- -

#include <xaxidma_hw.h>

- -

Whether has DRE shift.

- -

Referenced by XAxiDma_BdRingCreate().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET   0x38
-
- -

#include <xaxidma_hw.h>

- -

Whether has stscntrl strm.

- -

Referenced by XAxiDma_BdGetAppWord(), XAxiDma_BdRingCreate(), XAxiDma_BdSetAppWord(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_HW_NUM_BYTES   52
-
- -

#include <xaxidma_hw.h>

- -

Number of bytes hw used.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_ID_OFFSET   0x34
-
- -

#include <xaxidma_hw.h>

- -

Sw ID.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_MCCTL_OFFSET   0x10
-
- -

#include <xaxidma_hw.h>

- -

Multichannel Control Fields.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_MINIMUM_ALIGNMENT   0x40
-
- -

#include <xaxidma_hw.h>

- -

Minimum byte alignment requirement for descriptors to satisfy both hardware/software needs.

- -

Referenced by XAxiDma_BdRingCreate().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_NDESC_MSB_OFFSET   0x04
-
- -

#include <xaxidma_hw.h>

- -

Next descriptor pointer.

- -

Referenced by XAxiDma_BdRingCreate().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_NDESC_OFFSET   0x00
-
- -

#include <xaxidma_hw.h>

- -

Next descriptor pointer.

- -

Referenced by XAxiDma_BdRingCheck(), XAxiDma_BdRingCreate(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_NUM_WORDS   20U
-
- -

#include <xaxidma_hw.h>

- -

Total number of words for one BD.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_START_CLEAR   8
-
- -

#include <xaxidma_hw.h>

- -

Offset to start clear.

- -

Referenced by XAxiDma_BdRingClone().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET   0x14
-
- -

#include <xaxidma_hw.h>

- -

2D Transfer Sizes

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_ALL_ERR_MASK   0x70000000
-
- -

#include <xaxidma_hw.h>

- -

All errors.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_ALL_MASK   0xFC000000
-
- -

#include <xaxidma_hw.h>

- -

All status bits.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_COMPLETE_MASK   0x80000000
-
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_DEC_ERR_MASK   0x40000000
-
- -

#include <xaxidma_hw.h>

- -

Decode error.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_INT_ERR_MASK   0x10000000
-
- -

#include <xaxidma_hw.h>

- -

Internal err.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_OFFSET   0x1C
-
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_RXEOF_MASK   0x04000000
-
- -

#include <xaxidma_hw.h>

- -

Last rx pkt.

- -

Referenced by XAxiDma_BdRingFromHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_RXSOF_MASK   0x08000000
-
- -

#include <xaxidma_hw.h>

- -

First rx pkt.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_STS_SLV_ERR_MASK   0x20000000
-
- -

#include <xaxidma_hw.h>

- -

Slave error.

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_USR0_OFFSET   0x20
-
- -

#include <xaxidma_hw.h>

- -

User IP specific word0.

- -

Referenced by XAxiDma_BdGetAppWord(), XAxiDma_BdSetAppWord(), and XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_USR1_OFFSET   0x24
-
- -

#include <xaxidma_hw.h>

- -

User IP specific word1.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_USR2_OFFSET   0x28
-
- -

#include <xaxidma_hw.h>

- -

User IP specific word2.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_USR3_OFFSET   0x2C
-
- -

#include <xaxidma_hw.h>

- -

User IP specific word3.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_USR4_OFFSET   0x30
-
- -

#include <xaxidma_hw.h>

- -

User IP specific word4.

- -

Referenced by XAxiDma_DumpBd().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_WORDLEN_MASK   0xFF
-
- -

#include <xaxidma_hw.h>

- -

Whether has DRE mask.

- -

Referenced by XAxiDma_BdSetBufAddr().

- -
-
- -
-
- - - - -
#define XAXIDMA_BD_WORDLEN_SHIFT   0
-
- -

#include <xaxidma_hw.h>

- -

Whether has DRE shift.

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdClear( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
memset((void *)(((UINTPTR)(BdPtr)) + XAXIDMA_BD_START_CLEAR), 0, \
- -
#define XAXIDMA_BD_BYTES_TO_CLEAR
BD specific bytes to be cleared.
Definition: xaxidma_hw.h:248
-
#define XAXIDMA_BD_START_CLEAR
Offset to start clear.
Definition: xaxidma_hw.h:247
-
-

Zero out BD specific fields.

-

BD fields that are for the BD ring or for the system hardware build information are not touched.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdClear(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdGetActualLength( BdPtr,
 LengthMask 
)
-
- -

#include <xaxidma_bd.h>

-Value:
-
LengthMask)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
-

Get the actual transfer length of a BD.

-

The BD has completed in hw.

-

This function may not work if the BD is in cached memory.

-
Parameters
- - - -
BdPtris the BD to check on
LengthMaskis the Maximum Transfer Length.
-
-
-
Returns
None
-
Note
C-style signature: int XAxiDma_BdGetActualLength(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetARCache( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_ARCACHE_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Retrieve the ARCACHE field of the given BD previously set with XAxiDma_BdSetARCache.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetARCache(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetARUser( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_ARUSER_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Retrieve the ARUSER field of the given BD previously set with XAxiDma_BdSetARUser.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetARUser(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetBufAddr( BdPtr)   (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_BUFA_OFFSET))
-
- -

#include <xaxidma_bd.h>

- -

Get the BD's buffer address.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetBufAddr(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetCtrl( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
- -
#define XAXIDMA_BD_CTRL_LEN_OFFSET
Control/buffer length.
Definition: xaxidma_hw.h:227
-
#define XAXIDMA_BD_CTRL_ALL_MASK
All control bits.
Definition: xaxidma_hw.h:269
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
-

Get the control bits for the BD.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
The bit mask for the control of the BD
-
Note
C-style signature: u32 XAxiDma_BdGetCtrl(XAxiDma_Bd* BdPtr)
- -

Referenced by XAxiDma_BdRingToHw().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetId( BdPtr)   (XAxiDma_BdRead((BdPtr), XAXIDMA_BD_ID_OFFSET))
-
- -

#include <xaxidma_bd.h>

- -

Retrieve the ID field of the given BD previously set with XAxiDma_BdSetId.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetId(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdGetLength( BdPtr,
 LengthMask 
)
-
- -

#include <xaxidma_bd.h>

-Value:
-
LengthMask)
-
#define XAXIDMA_BD_CTRL_LEN_OFFSET
Control/buffer length.
Definition: xaxidma_hw.h:227
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
-

Retrieve the length field value from the given BD.

-

The returned value is the same as what was written with XAxiDma_BdSetLength(). Note that in the this value does not reflect the real length of received data. See the comments of XAxiDma_BdSetLength() for more details. To obtain the actual transfer length, use XAxiDma_BdGetActualLength().

-
Parameters
- - - -
BdPtris the BD to operate on.
LengthMaskis the Maximum Transfer Length.
-
-
-
Returns
The length value set in the BD.
-
Note
C-style signature: u32 XAxiDma_BdGetLength(XAxiDma_Bd* BdPtr)
- -

Referenced by XAxiDma_BdRingToHw().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetStride( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_STRIDE_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET
2D Transfer Sizes
Definition: xaxidma_hw.h:226
-
-

Retrieve the STRIDE field of the given BD previously set with XAxiDma_BdSetStride.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetStride(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetSts( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
- -
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
#define XAXIDMA_BD_STS_ALL_MASK
All status bits.
Definition: xaxidma_hw.h:282
-
-

Retrieve the status of a BD.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
Word at offset XAXIDMA_BD_DMASR_OFFSET. Use XAXIDMA_BD_STS_*** values defined in xaxidma_hw.h to interpret the returned value
-
Note
C-style signature: u32 XAxiDma_BdGetSts(XAxiDma_Bd* BdPtr)
- -

Referenced by XAxiDma_BdRingToHw().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetTDest( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_TDEST_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
-

Retrieve the TDest field of the RX BD previously set with i XAxiDma_BdSetTDest.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetTDest(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetTId( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_TID_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
-

Retrieve the TID field of the RX BD previously set with XAxiDma_BdSetTId.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetTId(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetTUser( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_TUSER_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
-

Retrieve the TUSER field of the RX BD previously set with XAxiDma_BdSetTUser.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetTUser(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdGetVSize( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
-
XAXIDMA_BD_VSIZE_FIELD_MASK)
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET
2D Transfer Sizes
Definition: xaxidma_hw.h:226
-
-

Retrieve the STRIDE field of the given BD previously set with XAxiDma_BdSetVSize.

-
Parameters
- - -
BdPtris the BD to operate on
-
-
-
Returns
None
-
Note
C-style signature: u32 XAxiDma_BdGetVSize(XAxiDma_Bd* BdPtr)
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdHwCompleted( BdPtr)
-
- -

#include <xaxidma_bd.h>

-Value:
- -
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STS_OFFSET
Status.
Definition: xaxidma_hw.h:228
-
#define XAXIDMA_BD_STS_COMPLETE_MASK
Completed.
Definition: xaxidma_hw.h:275
-
-

Check whether a BD has completed in hardware.

-

This BD has been submitted to hardware. The application can use this function to poll for the completion of the BD.

-

This function may not work if the BD is in cached memory.

-
Parameters
- - -
BdPtris the BD to check on
-
-
-
Returns
    -
  • 0 if not complete
  • -
  • XAXIDMA_BD_STS_COMPLETE_MASK if completed, may contain XAXIDMA_BD_STS_*_ERR_MASK bits.
  • -
-
-
Note
C-style signature: int XAxiDma_BdHwCompleted(XAxiDma_Bd* BdPtr)
- -

Referenced by XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRead( BaseAddress,
 Offset 
)   (*(u32 *)((UINTPTR)((void *)(BaseAddress)) + (u32)(Offset)))
-
- -

#include <xaxidma_bd.h>

- -

Read the given Buffer Descriptor word.

-
Parameters
- - - -
BaseAddressis the base address of the BD to read
Offsetis the word offset to be read
-
-
-
Returns
The 32-bit value of the field
-
Note
C-style signature: u32 XAxiDma_BdRead(u32 BaseAddress, u32 Offset)
- -

Referenced by XAxiDma_BdGetAppWord(), XAxiDma_BdRingCheck(), XAxiDma_BdRingClone(), XAxiDma_BdRingFromHw(), XAxiDma_BdRingToHw(), XAxiDma_BdSetAppWord(), XAxiDma_BdSetBufAddr(), XAxiDma_BdSetBufAddrMicroMode(), XAxiDma_BdSetCtrl(), XAxiDma_BdSetLength(), XAxiDma_DumpBd(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingAckIrq( RingPtr,
 Mask 
)
-
- -

#include <xaxidma_bdring.h>

-Value:
XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET,\
- -
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

Acknowledge asserted interrupts.

-

It modifies XAXIDMA_SR_OFFSET register. A mask bit set for an unasserted interrupt has no effect.

-
Parameters
- - - -
RingPtris the channel instance to operate on.
Maskare the interrupt signals to acknowledge
-
-
-
Note
C-style signature: void XAxiDma_BdRingAckIrq(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingBusy( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
-
((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
-
& XAXIDMA_IDLE_MASK) ? FALSE : TRUE))
-
#define XAXIDMA_IDLE_MASK
DMA channel idle.
Definition: xaxidma_hw.h:173
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAxiDma_BdRingHwIsStarted(RingPtr)
Check whether a DMA channel is started, meaning the channel is not halted.
Definition: xaxidma_bdring.h:369
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

Check if the current DMA channel is busy with a DMA operation.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
    -
  • 1 if the DMA is busy.
  • -
  • 0 otherwise
  • -
-
-
Note
C-style signature: int XAxiDma_BdRingBusy(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingCntCalc( Alignment,
 Bytes 
)   (uint32_t)((Bytes)/((sizeof(XAxiDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
-
- -

#include <xaxidma_bdring.h>

- -

Use this macro at initialization time to determine how many BDs will fit within the given memory constraints.

-

The results of this macro can be provided to XAxiDma_BdRingCreate().

-
Parameters
- - - -
Alignmentspecifies what byte alignment the BDs must fall on and must be a power of 2 to get an accurate calculation (32, 64, 126,...)
Bytesis the number of bytes to be used to store BDs.
-
-
-
Returns
Number of BDs that can fit in the given memory area
-
Note
C-style signature: int XAxiDma_BdRingCntCalc(u32 Alignment, u32 Bytes) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetCnt( RingPtr)   ((RingPtr)->AllCnt)
-
- -

#include <xaxidma_bdring.h>

- -

Return the total number of BDs allocated by this channel with XAxiDma_BdRingCreate().

-
Parameters
- - -
RingPtris the BD ring to operate on.
-
-
-
Returns
The total number of BDs allocated for this channel.
-
Note
C-style signature: int XAxiDma_BdRingGetCnt(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetCurrBd( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_Bd *)XAxiDma_ReadReg((RingPtr)->ChanBase, \
- -
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
UINTPTR XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS]
The XAxiDma_Bd is the type for a buffer descriptor (BD).
Definition: xaxidma_bd.h:135
-
#define XAXIDMA_CDESC_OFFSET
Current descriptor pointer.
Definition: xaxidma_hw.h:128
-
-

Get the BD a BD ring is processing.

-
Parameters
- - -
RingPtris the BD ring to operate on.
-
-
-
Returns
The current BD that the BD ring is working on
-
Note
C-style signature: XAxiDma_Bd * XAxiDma_BdRingGetCurrBd(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetError( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
- -
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_ERR_ALL_MASK
All errors.
Definition: xaxidma_hw.h:184
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

Get error bits of a DMA channel.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
Rrror bits in the status register, they should be interpreted with XAXIDMA_ERR_*_MASK defined in xaxidma_hw.h
-
Note
C-style signature: u32 XAxiDma_BdRingGetError(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetFreeCnt( RingPtr)   ((RingPtr)->FreeCnt)
-
- -

#include <xaxidma_bdring.h>

- -

Return the number of BDs allocatable with XAxiDma_BdRingAlloc() for pre- processing.

-
Parameters
- - -
RingPtris the BD ring to operate on.
-
-
-
Returns
The number of BDs currently allocatable.
-
Note
C-style signature: int XAxiDma_BdRingGetFreeCnt(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetIrq( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
- -
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

Retrieve the contents of the channel's IRQ register XAXIDMA_SR_OFFSET.

-

This operation can be used to see which interrupts are pending.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
Current contents of the IRQ_OFFSET register. Use XAXIDMA_IRQ_*** values defined in xaxidma_hw.h to interpret the returned value.
-
Note
C-style signature: u32 XAxiDma_BdRingGetIrq(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingGetSr( RingPtr)   XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET)
-
- -

#include <xaxidma_bdring.h>

- -

Retrieve the contents of the channel status register.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
Current contents of status register
-
Note
C-style signature: u32 XAxiDma_BdRingGetSr(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingHwIsStarted( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
((XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_SR_OFFSET) \
-
& XAXIDMA_HALTED_MASK) ? FALSE : TRUE)
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_HALTED_MASK
DMA channel halted.
Definition: xaxidma_hw.h:172
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

Check whether a DMA channel is started, meaning the channel is not halted.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
    -
  • 1 if channel is started
  • -
  • 0 otherwise
  • -
-
-
Note
C-style signature: int XAxiDma_BdRingHwIsStarted(XAxiDma_BdRing* RingPtr)
- -

Referenced by XAxiDma_StartBdRingHw(), and XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingIntDisable( RingPtr,
 Mask 
)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \
-
XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) & \
-
~((Mask) & XAXIDMA_IRQ_ALL_MASK)))
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

Clear interrupt enable bits for a channel.

-

It modifies the XAXIDMA_CR_OFFSET register.

-
Parameters
- - - -
RingPtris the channel instance to operate on.
Maskconsists of the interrupt signals to disable.Bits not specified in the Mask are not affected.
-
-
-
Note
C-style signature: void XAxiDma_BdRingIntDisable(XAxiDma_BdRing* RingPtr, u32 Mask) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingIntEnable( RingPtr,
 Mask 
)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_WriteReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET, \
-
XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \
-
| ((Mask) & XAXIDMA_IRQ_ALL_MASK)))
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

Set interrupt enable bits for a channel.

-

This operation will modify the XAXIDMA_CR_OFFSET register.

-
Parameters
- - - -
RingPtris the channel instance to operate on.
Maskconsists of the interrupt signals to enable.Bits not specified in the mask are not affected.
-
-
-
Note
C-style signature: void XAxiDma_BdRingIntEnable(XAxiDma_BdRing* RingPtr, u32 Mask) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingIntGetEnabled( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
(XAxiDma_ReadReg((RingPtr)->ChanBase, XAXIDMA_CR_OFFSET) \
- -
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

Get enabled interrupts of a channel.

-

It is in XAXIDMA_CR_OFFSET register.

-
Parameters
- - -
RingPtris the channel instance to operate on.
-
-
-
Returns
Enabled interrupts of a channel. Use XAXIDMA_IRQ_* defined in xaxidma_hw.h to interpret this returned value.
-
Note
C-style signature: u32 XAxiDma_BdRingIntGetEnabled(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingMemCalc( Alignment,
 NumBd 
)   (int)((sizeof(XAxiDma_Bd)+((Alignment)-1)) & ~((Alignment)-1))*(NumBd)
-
- -

#include <xaxidma_bdring.h>

- -

Use this macro at initialization time to determine how many bytes of memory are required to contain a given number of BDs at a given alignment.

-
Parameters
- - - -
Alignmentspecifies what byte alignment the BDs must fall on. This parameter must be a power of 2 to get an accurate calculation (32, 64,128,...)
NumBdis the number of BDs to calculate memory size requirements
-
-
-
Returns
The number of bytes of memory required to create a BD list with the given memory constraints.
-
Note
C-style signature: int XAxiDma_BdRingMemCalc(u32 Alignment, u32 NumBd) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingNext( RingPtr,
 BdPtr 
)
-
- -

#include <xaxidma_bdring.h>

-Value:
(((UINTPTR)(BdPtr) >= (RingPtr)->LastBdAddr) ? \
-
(UINTPTR)(RingPtr)->FirstBdAddr : \
-
(UINTPTR)((UINTPTR)(BdPtr) + (RingPtr)->Separation))
-
-

Return the next BD in the ring.

-
Parameters
- - - -
RingPtris the BD ring to operate on.
BdPtris the current BD.
-
-
-
Returns
The next BD in the ring relative to the BdPtr parameter.
-
Note
C-style signature: XAxiDma_Bd *XAxiDma_BdRingNext(XAxiDma_BdRing* RingPtr, XAxiDma_Bd *BdPtr) This function is used only when system is configured as SG mode
- -

Referenced by XAxiDma_BdRingFromHw(), XAxiDma_BdRingToHw(), and XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdRingPrev( RingPtr,
 BdPtr 
)
-
- -

#include <xaxidma_bdring.h>

-Value:
(((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ? \
-
(XAxiDma_Bd*)(RingPtr)->LastBdAddr : \
-
(XAxiDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
-
UINTPTR XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS]
The XAxiDma_Bd is the type for a buffer descriptor (BD).
Definition: xaxidma_bd.h:135
-
-

Return the previous BD in the ring.

-
Parameters
- - - -
RingPtris the DMA channel to operate on.
BdPtris the current BD.
-
-
-
Returns
The previous BD in the ring relative to the BdPtr parameter.
-
Note
C-style signature: XAxiDma_Bd *XAxiDma_BdRingPrev(XAxiDma_BdRing* RingPtr, XAxiDma_Bd *BdPtr) This function is used only when system is configured as SG mode
- -
-
- -
-
- - - - - - - - -
#define XAxiDma_BdRingSnapShotCurrBd( RingPtr)
-
- -

#include <xaxidma_bdring.h>

-Value:
{ \
-
if (!RingPtr->IsRxChannel) { \
-
(RingPtr)->BdaRestart = \
-
XAxiDma_ReadReg((RingPtr)->ChanBase, \
- -
} else { \
-
if (!RingPtr->RingIndex) { \
-
(RingPtr)->BdaRestart = \
- -
(RingPtr)->ChanBase, \
- -
} else { \
-
(RingPtr)->BdaRestart = \
- -
(RingPtr)->ChanBase, \
- -
(RingPtr->RingIndex - 1) * \
- -
} \
-
} \
-
}
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_RX_NDESC_OFFSET
Rx Next Descriptor Offset.
Definition: xaxidma_hw.h:148
-
#define XAXIDMA_RX_CDESC0_OFFSET
Multi-Channel DMA Descriptor Offsets.
Definition: xaxidma_hw.h:144
-
#define XAXIDMA_CDESC_OFFSET
Current descriptor pointer.
Definition: xaxidma_hw.h:128
-
-

Snap shot the latest BD a BD ring is processing.

-
Parameters
- - -
RingPtris the BD ring to operate on.
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing* RingPtr) This function is used only when system is configured as SG mode
- -

Referenced by XAxiDma_Reset().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetARCache( BdPtr,
 ARCache 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_ARCACHE_FIELD_MASK); \
-
val |= ((u32)(ARCache) << XAXIDMA_BD_ARCACHE_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Set the ARCACHE field of the given BD.

-

This signal provides additional information about the cacheable characteristics of the transfer.

-
Parameters
- - - -
BdPtris the BD to operate on
ARCacheis a 8 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetARCache(XAxiDma_Bd* BdPtr, void ARCache)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetARUser( BdPtr,
 ARUser 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_ARUSER_FIELD_MASK); \
-
val |= ((u32)(ARUser) << XAXIDMA_BD_ARUSER_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Set the ARUSER field of the given BD.

-

Sideband signals used for user defined information.

-
Parameters
- - - -
BdPtris the BD to operate on
ARUseris a 8 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetARUser(XAxiDma_Bd* BdPtr, void ARUser)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetId( BdPtr,
 Id 
)   (XAxiDma_BdWrite((BdPtr), XAXIDMA_BD_ID_OFFSET, (u32)(Id)))
-
- -

#include <xaxidma_bd.h>

- -

Set the ID field of the given BD.

-

The ID is an arbitrary piece of data the application can associate with a specific BD.

-
Parameters
- - - -
BdPtris the BD to operate on
Idis a 32 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetId(XAxiDma_Bd* BdPtr, void Id)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetStride( BdPtr,
 Stride 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_STRIDE_FIELD_MASK); \
-
val |= ((u32)(Stride) << XAXIDMA_BD_STRIDE_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET
2D Transfer Sizes
Definition: xaxidma_hw.h:226
-
-

Set the STRIDE field of the given BD.

-

It is the address distance between the first address of successive horizontal reads.

-
Parameters
- - - -
BdPtris the BD to operate on
Strideis a 32 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetStride(XAxiDma_Bd* BdPtr, void Stride)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetTDest( BdPtr,
 TDest 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_TDEST_FIELD_MASK); \
-
val |= ((u32)(TDest) << XAXIDMA_BD_TDEST_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Set the TDEST field of the TX BD.

-

Provides coarse routing information for the data stream.

-
Parameters
- - - -
BdPtris the BD to operate on
TDestis a 8 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetTDest(XAxiDma_Bd* BdPtr, void TDest)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetTId( BdPtr,
 TId 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_TID_FIELD_MASK); \
-
val |= ((u32)(TId) << XAXIDMA_BD_TID_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Set the TID field of the TX BD.

-

Provides a stream identifier and can be used to differentiate between multiple streams of data that are being transferred across the same interface.

-
Parameters
- - - -
BdPtris the BD to operate on
TIdis a 8 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetTId(XAxiDma_Bd* BdPtr, void TId)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetTUser( BdPtr,
 TUser 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_TUSER_FIELD_MASK); \
-
val |= ((u32)(TUser) << XAXIDMA_BD_TUSER_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_MCCTL_OFFSET
Multichannel Control Fields.
Definition: xaxidma_hw.h:225
-
-

Set the TUSER field of the TX BD.

-

User defined sideband signaling.

-
Parameters
- - - -
BdPtris the BD to operate on
TUseris a 8 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetTUser(XAxiDma_Bd* BdPtr, void TUser)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdSetVSize( BdPtr,
 VSize 
)
-
- -

#include <xaxidma_bd.h>

-Value:
{ \
-
u32 val; \
- -
~XAXIDMA_BD_VSIZE_FIELD_MASK); \
-
val |= ((u32)(VSize) << XAXIDMA_BD_VSIZE_FIELD_SHIFT); \
- -
}
-
#define XAxiDma_BdWrite(BaseAddress, Offset, Data)
Write the given Buffer Descriptor word.
Definition: xaxidma_bd.h:189
-
#define XAxiDma_BdRead(BaseAddress, Offset)
Read the given Buffer Descriptor word.
Definition: xaxidma_bd.h:170
-
#define XAXIDMA_BD_STRIDE_VSIZE_OFFSET
2D Transfer Sizes
Definition: xaxidma_hw.h:226
-
-

Set the VSIZE field of the given BD.

-

Number of horizontal lines for strided access.

-
Parameters
- - - -
BdPtris the BD to operate on
VSizeis a 32 bit quantity to set in the BD
-
-
-
Returns
None
-
Note
C-style signature: void XAxiDma_BdSetVSize(XAxiDma_Bd* BdPtr, void VSize)
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
#define XAxiDma_BdWrite( BaseAddress,
 Offset,
 Data 
)   (*(u32 *)((UINTPTR)(void *)(BaseAddress) + (u32)(Offset))) = (u32)(Data)
-
- -

#include <xaxidma_bd.h>

- -

Write the given Buffer Descriptor word.

-
Parameters
- - - - -
BaseAddressis the base address of the BD to write
Offsetis the word offset to be written
Datais the 32-bit value to write to the field
-
-
-
Returns
None.
-
Note
C-style signature: void XAxiDma_BdWrite(u32 BaseAddress, u32 RegOffset, u32 Data)
- -

Referenced by XAxiDma_BdRingClone(), XAxiDma_BdRingCreate(), XAxiDma_BdRingToHw(), XAxiDma_BdSetAppWord(), XAxiDma_BdSetBufAddr(), XAxiDma_BdSetBufAddrMicroMode(), XAxiDma_BdSetCtrl(), and XAxiDma_BdSetLength().

- -
-
- -
-
- - - - -
#define XAXIDMA_BUFFLEN_OFFSET   0x00000028
-
- -

#include <xaxidma_hw.h>

- -

Tail descriptor pointer.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_CDESC_MSB_OFFSET   0x0000000C
-
- -

#include <xaxidma_hw.h>

- -

Current descriptor pointer.

- -

Referenced by XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - -
#define XAXIDMA_CDESC_OFFSET   0x00000008
-
- -

#include <xaxidma_hw.h>

- -

Current descriptor pointer.

- -

Referenced by XAxiDma_BdRingDumpRegs(), and XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - -
#define XAXIDMA_COALESCE_MASK   0x00FF0000
-
- -

#include <xaxidma_hw.h>

- -

Coalesce counter.

- -

Referenced by XAxiDma_BdRingGetCoalesce(), and XAxiDma_BdRingSetCoalesce().

- -
-
- -
-
- - - - -
#define XAXIDMA_CR_CYCLIC_MASK   0x00000010
-
- -

#include <xaxidma_hw.h>

- -

Cyclic Mode.

- -

Referenced by XAxiDma_SelectCyclicMode().

- -
-
- -
-
- - - - -
#define XAXIDMA_CR_KEYHOLE_MASK   0x00000008
-
- -

#include <xaxidma_hw.h>

- -

Keyhole feature.

- -

Referenced by XAxiDma_SelectKeyHole().

- -
-
- - - -
-
- - - - -
#define XAXIDMA_CR_RESET_MASK   0x00000004
-
- -

#include <xaxidma_hw.h>

- -

Reset DMA engine.

- -

Referenced by XAxiDma_Reset(), and XAxiDma_ResetIsDone().

- -
-
- -
-
- - - - -
#define XAXIDMA_CR_RUNSTOP_MASK   0x00000001
-
- -

#include <xaxidma_hw.h>

- -

Start/stop DMA channel.

- -

Referenced by XAxiDma_Pause(), XAxiDma_SimpleTransfer(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_DELAY_MASK   0xFF000000
-
- -

#include <xaxidma_hw.h>

- -

Delay timeout counter.

- -

Referenced by XAxiDma_BdRingGetCoalesce(), and XAxiDma_BdRingSetCoalesce().

- -
-
- -
-
- - - - -
#define XAXIDMA_DESC_LSB_MASK   (0xFFFFFFC0U)
-
-
- -
-
- - - - -
#define XAXIDMA_DESTADDR_MSB_OFFSET   0x0000001C
-
- -

#include <xaxidma_hw.h>

- -

Simple mode destination address pointer.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_DESTADDR_OFFSET   0x00000018
-
- -

#include <xaxidma_hw.h>

- -

Simple mode destination address pointer.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_ALL_MASK   0x00000770
-
- -

#include <xaxidma_hw.h>

- -

All errors.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_DECODE_MASK   0x00000040
-
- -

#include <xaxidma_hw.h>

- -

Datamover decode err.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_INTERNAL_MASK   0x00000010
-
- -

#include <xaxidma_hw.h>

- -

Datamover internal err.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_SG_DEC_MASK   0x00000400
-
- -

#include <xaxidma_hw.h>

- -

SG decode err.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_SG_INT_MASK   0x00000100
-
- -

#include <xaxidma_hw.h>

- -

SG internal err.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_SG_SLV_MASK   0x00000200
-
- -

#include <xaxidma_hw.h>

- -

SG slave err.

- -
-
- -
-
- - - - -
#define XAXIDMA_ERR_SLAVE_MASK   0x00000020
-
- -

#include <xaxidma_hw.h>

- -

Datamover slave err.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_GetRxIndexRing( InstancePtr,
 RingIndex 
)   (&((InstancePtr)->RxBdRing[RingIndex]))
-
- -

#include <xaxidma.h>

- -

Get Receive (Rx) Ring ptr of a Index.

-

Warning: This has a different API than the LLDMA driver. It now returns the pointer to the BD ring.

-
Parameters
- - - -
InstancePtris a pointer to the DMA engine instance to be worked on.
RingIndexis the channel Index.
-
-
-
Returns
Pointer to the Rx Ring
-
Note
C-style signature: XAxiDma_BdRing * XAxiDma_GetRxIndexRing(XAxiDma * InstancePtr, int RingIndex) This function is used only when system is configured as SG mode
- -

Referenced by XAxiDma_Pause(), XAxiDma_Reset(), and XAxiDma_Resume().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_GetRxRing( InstancePtr)   (&((InstancePtr)->RxBdRing[0]))
-
- -

#include <xaxidma.h>

- -

Get Receive (Rx) Ring ptr.

-

Warning: This has a different API than the LLDMA driver. It now returns the pointer to the BD ring.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
Pointer to the Rx Ring
-
Note
C-style signature: XAxiDma_BdRing * XAxiDma_GetRxRing(XAxiDma * InstancePtr) This function is used only when system is configured as SG mode
- -

Referenced by XAxiDma_ResetIsDone().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_GetTxRing( InstancePtr)   (&((InstancePtr)->TxBdRing))
-
- -

#include <xaxidma.h>

- -

Get Transmit (Tx) Ring ptr.

-

Warning: This has a different API than the LLDMA driver. It now returns the pointer to the BD ring.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
Pointer to the Tx Ring
-
Note
C-style signature: XAxiDma_BdRing * XAxiDma_GetTxRing(XAxiDma * InstancePtr) This function is used only when system is configured as SG mode
- -

Referenced by XAxiDma_Pause(), XAxiDma_Reset(), XAxiDma_ResetIsDone(), and XAxiDma_Resume().

- -
-
- -
-
- - - - -
#define XAXIDMA_HALTED_MASK   0x00000001
-
- -

#include <xaxidma_hw.h>

- -

DMA channel halted.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - - - - - -
#define XAxiDma_HasSg( InstancePtr)   ((InstancePtr)->HasSg) ? TRUE : FALSE
-
- -

#include <xaxidma.h>

- -

This function checks whether system is configured as Simple or Scatter Gather mode.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
    -
  • TRUE if configured as SG mode
  • -
  • FALSE if configured as simple mode
  • -
-
-
Note
None
- -

Referenced by XAxiDma_Pause(), XAxiDma_Reset(), XAxiDma_Resume(), and XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_IDLE_MASK   0x00000002
-
- -

#include <xaxidma_hw.h>

- -

DMA channel idle.

- -

Referenced by XAxiDma_Busy().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
#define XAxiDma_IntrAckIrq( InstancePtr,
 Mask,
 Direction 
)
-
- -

#include <xaxidma.h>

-Value:
XAxiDma_WriteReg((InstancePtr)->RegBase + \
- - -
#define XAXIDMA_RX_OFFSET
RX channel registers base offset.
Definition: xaxidma_hw.h:118
-
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

This function acknowledges the interrupts that are specified in Mask.

-
Parameters
- - - - -
InstancePtris the driver instance we are working on
Maskis the mask for the interrupts to be acknowledge
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
None
-
Note
None.
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
#define XAxiDma_IntrDisable( InstancePtr,
 Mask,
 Direction 
)
-
- -

#include <xaxidma.h>

-Value:
XAxiDma_WriteReg((InstancePtr)->RegBase + \
- -
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
- -
& ~(Mask & XAXIDMA_IRQ_ALL_MASK))
-
#define XAXIDMA_RX_OFFSET
RX channel registers base offset.
Definition: xaxidma_hw.h:118
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

This function disables interrupts specified by the Mask.

-

Interrupts that are not in the mask are not affected.

-
Parameters
- - - - -
InstancePtris the driver instance we are working on
Maskis the mask for the interrupts to be disabled
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
None
-
Note
None
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
#define XAxiDma_IntrEnable( InstancePtr,
 Mask,
 Direction 
)
-
- -

#include <xaxidma.h>

-Value:
XAxiDma_WriteReg((InstancePtr)->RegBase + \
- -
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
- - -
#define XAXIDMA_RX_OFFSET
RX channel registers base offset.
Definition: xaxidma_hw.h:118
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAxiDma_WriteReg(BaseAddress, RegOffset, Data)
Write the given register.
Definition: xaxidma_hw.h:350
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

This function enables interrupts specified by the Mask in specified direction, Interrupts that are not in the mask are not affected.

-
Parameters
- - - - -
InstancePtris the driver instance we are working on
Maskis the mask for the interrupts to be enabled
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
None
-
Note
None
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_IntrGetEnabled( InstancePtr,
 Direction 
)
-
- -

#include <xaxidma.h>

-Value:
XAxiDma_ReadReg((InstancePtr)->RegBase + \
- - -
#define XAXIDMA_RX_OFFSET
RX channel registers base offset.
Definition: xaxidma_hw.h:118
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_CR_OFFSET
Channel control.
Definition: xaxidma_hw.h:126
-
-

This function gets the mask for the interrupts that are currently enabled.

-
Parameters
- - - -
InstancePtris the driver instance we are working on
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
The bit mask for the interrupts that are currently enabled
-
Note
None
- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_IntrGetIrq( InstancePtr,
 Direction 
)
-
- -

#include <xaxidma.h>

-Value:
(XAxiDma_ReadReg((InstancePtr)->RegBase + \
- - -
#define XAXIDMA_RX_OFFSET
RX channel registers base offset.
Definition: xaxidma_hw.h:118
-
#define XAxiDma_ReadReg(BaseAddress, RegOffset)
Read the given register.
Definition: xaxidma_hw.h:331
-
#define XAXIDMA_IRQ_ALL_MASK
All interrupts.
Definition: xaxidma_hw.h:194
-
#define XAXIDMA_SR_OFFSET
Status.
Definition: xaxidma_hw.h:127
-
-

This function gets the interrupts that are asserted.

-
Parameters
- - - -
InstancePtris the driver instance we are working on
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
The bit mask for the interrupts asserted.
-
Note
None
- -
-
- -
-
- - - - -
#define XAXIDMA_IRQ_ALL_MASK   0x00007000
-
- -

#include <xaxidma_hw.h>

- -

All interrupts.

- -
-
- -
-
- - - - -
#define XAXIDMA_IRQ_DELAY_MASK   0x00002000
-
- -

#include <xaxidma_hw.h>

- -

Delay interrupt.

- -
-
- -
-
- - - - -
#define XAXIDMA_IRQ_ERROR_MASK   0x00004000
-
- -

#include <xaxidma_hw.h>

- -

Error interrupt.

- -
-
- -
-
- - - - -
#define XAXIDMA_IRQ_IOC_MASK   0x00001000
-
- -

#include <xaxidma_hw.h>

- -

Completion intr.

- -
-
- -
-
- - - - -
#define XAXIDMA_MICROMODE_MIN_BUF_ALIGN   0xFFF
-
- -

#include <xaxidma_hw.h>

- -

Minimum byte alignment requirement for buffer address in Micro DMA mode.

- -

Referenced by XAxiDma_BdSetBufAddrMicroMode(), and XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
#define XAxiDma_ReadReg( BaseAddress,
 RegOffset 
)   XAxiDma_In32((BaseAddress) + (RegOffset))
-
- -

#include <xaxidma_hw.h>

- -

Read the given register.

-
Parameters
- - - -
BaseAddressis the base address of the device
RegOffsetis the register offset to be read
-
-
-
Returns
The 32-bit value of the register
-
Note
C-style signature: u32 XAxiDma_ReadReg(u32 BaseAddress, u32 RegOffset)
- -

Referenced by XAxiDma_BdRingDumpRegs(), XAxiDma_BdRingGetCoalesce(), XAxiDma_BdRingSetCoalesce(), XAxiDma_Busy(), XAxiDma_Pause(), XAxiDma_ResetIsDone(), XAxiDma_SelectCyclicMode(), XAxiDma_SelectKeyHole(), XAxiDma_SimpleTransfer(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_CDESC0_MSB_OFFSET   0x00000044
-
- -

#include <xaxidma_hw.h>

- -

Rx Current Descriptor 0.

- -

Referenced by XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_CDESC0_OFFSET   0x00000040
-
- -

#include <xaxidma_hw.h>

- -

Multi-Channel DMA Descriptor Offsets.

-

Rx Current Descriptor 0

- -

Referenced by XAxiDma_BdRingDumpRegs(), and XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_NDESC_OFFSET   0x00000020
-
- -

#include <xaxidma_hw.h>

- -

Rx Next Descriptor Offset.

- -

Referenced by XAxiDma_BdRingDumpRegs(), XAxiDma_BdRingToHw(), XAxiDma_StartBdRingHw(), and XAxiDma_UpdateBdRingCDesc().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_OFFSET   0x00000030
-
- -

#include <xaxidma_hw.h>

- -

RX channel registers base offset.

- -

Referenced by XAxiDma_Busy(), XAxiDma_CfgInitialize(), XAxiDma_Reset(), XAxiDma_SelectCyclicMode(), and XAxiDma_SelectKeyHole().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_TDESC0_MSB_OFFSET   0x0000004C
-
- -

#include <xaxidma_hw.h>

- -

Rx Tail Descriptor 0.

- -

Referenced by XAxiDma_BdRingToHw(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_RX_TDESC0_OFFSET   0x00000048
-
- -

#include <xaxidma_hw.h>

- -

Rx Tail Descriptor 0.

- -

Referenced by XAxiDma_BdRingDumpRegs(), XAxiDma_BdRingToHw(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_SGCTL_OFFSET   0x0000002c
-
- -

#include <xaxidma_hw.h>

- -

SG Control Register.

- -
-
- -
-
- - - - -
#define XAXIDMA_SR_OFFSET   0x00000004
-
- -

#include <xaxidma_hw.h>

- -

Status.

- -

Referenced by XAxiDma_BdRingDumpRegs(), XAxiDma_Busy(), and XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_SRCADDR_MSB_OFFSET   0x0000001C
-
- -

#include <xaxidma_hw.h>

- -

Simple mode source address pointer.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_SRCADDR_OFFSET   0x00000018
-
- -

#include <xaxidma_hw.h>

- -

Simple mode source address pointer.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - -
#define XAXIDMA_TDESC_MSB_OFFSET   0x00000014
-
- -

#include <xaxidma_hw.h>

- -

Tail descriptor pointer.

- -

Referenced by XAxiDma_BdRingToHw(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_TDESC_OFFSET   0x00000010
-
- -

#include <xaxidma_hw.h>

- -

Tail descriptor pointer.

- -

Referenced by XAxiDma_BdRingDumpRegs(), XAxiDma_BdRingToHw(), and XAxiDma_StartBdRingHw().

- -
-
- -
-
- - - - -
#define XAXIDMA_TX_OFFSET   0x00000000
-
- -

#include <xaxidma_hw.h>

- -

TX channel registers base offset.

- -

Referenced by XAxiDma_CfgInitialize(), and XAxiDma_Reset().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
#define XAxiDma_WriteReg( BaseAddress,
 RegOffset,
 Data 
)   XAxiDma_Out32((BaseAddress) + (RegOffset), (Data))
-
- -

#include <xaxidma_hw.h>

- -

Write the given register.

-
Parameters
- - - - -
BaseAddressis the base address of the device
RegOffsetis the register offset to be written
Datais the 32-bit value to write to the register
-
-
-
Returns
None.
-
Note
C-style signature: void XAxiDma_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
- -

Referenced by XAxiDma_BdRingSetCoalesce(), XAxiDma_BdRingToHw(), XAxiDma_Pause(), XAxiDma_Reset(), XAxiDma_SelectCyclicMode(), XAxiDma_SelectKeyHole(), XAxiDma_SimpleTransfer(), XAxiDma_StartBdRingHw(), and XAxiDma_UpdateBdRingCDesc().

- -
-
-

Typedef Documentation

- -
-
- - - - -
typedef struct XAxiDma XAxiDma
-
- -

#include <xaxidma.h>

- -

The XAxiDma driver instance data.

-

An instance must be allocated for each DMA engine in use.

- -
-
- -
-
- - - - -
typedef UINTPTR XAxiDma_Bd[XAXIDMA_BD_NUM_WORDS]
-
- -

#include <xaxidma_bd.h>

- -

The XAxiDma_Bd is the type for a buffer descriptor (BD).

- -
-
-

Function Documentation

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
u32 XAxiDma_BdGetAppWord (XAxiDma_BdBdPtr,
int Offset,
int * Valid 
)
-
- -

#include <xaxidma_bd.c>

- -

Get the APP word at the specified APP word offset for a BD.

-
Parameters
- - - - -
BdPtris the BD to operate on.
Offsetis the offset inside the APP word, it is valid from 0 to 4
Validis to tell the caller whether parameters are valid
-
-
-
Returns
The APP word. Passed in parameter Valid holds 0 for failure, and 1 for success.
-
Note
This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_HAS_STSCNTRL_OFFSET, XAXIDMA_BD_USR0_OFFSET, and XAxiDma_BdRead.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingAlloc (XAxiDma_BdRingRingPtr,
int NumBd,
XAxiDma_Bd ** BdSetPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Reserve locations in the BD ring.

-

The set of returned BDs may be modified in preparation for future DMA transactions. Once the BDs are ready to be submitted to hardware, the application must call XAxiDma_BdRingToHw() in the same order which they were allocated here. Example:

-
-       NumBd = 2;
-       Status = XDsma_RingBdAlloc(MyRingPtr, NumBd, &MyBdSet);
       if (Status != XST_SUCCESS)
-       {
-           // Not enough BDs available for the request
-       }
       CurBd = MyBdSet;
-       for (i=0; i<NumBd; i++)
-       {
-           // Prepare CurBd.....
           // Onto next BD
-           CurBd = XAxiDma_BdRingNext(MyRingPtr, CurBd);
-       }
       // Give list to hardware
-       Status = XAxiDma_BdRingToHw(MyRingPtr, NumBd, MyBdSet);
-

A more advanced use of this function may allocate multiple sets of BDs. They must be allocated and given to hardware in the correct sequence:

-       // Legal
-       XAxiDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
       // Legal
-       XAxiDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
-       XAxiDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
-       XAxiDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
       // Not legal
-       XAxiDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
-       XAxiDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
-       XAxiDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
-

Use the API defined in xaxidmabd.h to modify individual BDs. Traversal of the BD set can be done using XAxiDma_BdRingNext() and XAxiDma_BdRingPrev().

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
NumBdis the number of BDs to allocate
BdSetPtris an output parameter, it points to the first BD available for modification.
-
-
-
Returns
    -
  • XST_SUCCESS if the requested number of BDs were returned in the BdSetPtr parameter.
  • -
  • XST_INVALID_PARAM if passed in NumBd is not positive
  • -
  • XST_FAILURE if there were not enough free BDs to satisfy the request.
  • -
-
-
Note
This function should not be preempted by another XAxiDma_BdRing function call that modifies the BD space. It is the caller's responsibility to provide a mutual exclusion mechanism.
-

Do not modify more BDs than the number requested with the NumBd parameter. Doing so will lead to data corruption and system instability.

-

This function can be used only when DMA is in SG mode

- -

References XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::FreeHead, and XAxiDma_BdRing::PreCnt.

- -
-
- -
-
- - - - - - - - -
int XAxiDma_BdRingCheck (XAxiDma_BdRingRingPtr)
-
- -

#include <xaxidma_bdring.c>

- -

Check the internal data structures of the BD ring for the provided channel.

-

The following checks are made:

-
    -
  • The BD ring is linked correctly in physical address space.
  • -
  • The internal pointers point to BDs in the ring.
  • -
  • The internal counters add up.
  • -
-

The channel should be stopped (through XAxiDma_Pause() or XAxiDma_Reset()) prior to calling this function.

-
Parameters
- - -
RingPtris a pointer to the descriptor ring to be worked on.
-
-
-
Returns
    -
  • XST_SUCCESS if no errors were found.
  • -
  • XST_DMA_SG_NO_LIST if the ring has not been created.
  • -
  • XST_IS_STARTED if the channel is not stopped.
  • -
  • XST_DMA_SG_LIST_ERROR if a problem is found with the internal data structures. If this value is returned, the channel should be reset,and the BD ring should be recreated through XAxiDma_BdRingCreate() to avoid data corruption or system instability.
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::AllCnt, XAxiDma_BdRing::FirstBdAddr, XAxiDma_BdRing::FirstBdPhysAddr, XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::FreeHead, XAxiDma_BdRing::HwCnt, XAxiDma_BdRing::HwHead, XAxiDma_BdRing::HwTail, XAxiDma_BdRing::LastBdAddr, XAxiDma_BdRing::PostCnt, XAxiDma_BdRing::PostHead, XAxiDma_BdRing::PreCnt, XAxiDma_BdRing::PreHead, XAxiDma_BdRing::RunState, XAxiDma_BdRing::Separation, XAXIDMA_BD_NDESC_OFFSET, and XAxiDma_BdRead.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingClone (XAxiDma_BdRingRingPtr,
XAxiDma_BdSrcBdPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Clone the given BD into every BD in the ring.

-

Only the fields offset from XAXIDMA_BD_START_CLEAR are copied, for XAXIDMA_BD_BYTES_TO_CLEAR bytes. This covers: BufferAddr, Control/Buffer length, status, APP words 0 - 4, and software ID fields.

-

This function can be called only when all BDs are in the free group such as immediately after creation of the ring. This prevents modification of BDs while they are in use by hardware or the application.

-
Parameters
- - - -
RingPtris the BD ring instance to be worked on.
SrcBdPtris the source BD template to be cloned into the list.
-
-
-
Returns
    -
  • XST_SUCCESS if the list was modified.
  • -
  • XST_DMA_SG_NO_LIST if a list has not been created.
  • -
  • XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
  • -
  • XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under hardware or application control.
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::AllCnt, XAxiDma_BdRing::FirstBdAddr, XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::RunState, XAxiDma_BdRing::Separation, XAXIDMA_BD_BYTES_TO_CLEAR, XAXIDMA_BD_START_CLEAR, XAXIDMA_BD_STS_COMPLETE_MASK, XAXIDMA_BD_STS_OFFSET, XAxiDma_BdRead, and XAxiDma_BdWrite.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 XAxiDma_BdRingCreate (XAxiDma_BdRingRingPtr,
UINTPTR PhysAddr,
UINTPTR VirtAddr,
u32 Alignment,
int BdCount 
)
-
- -

#include <xaxidma_bdring.c>

- -

Using a memory segment allocated by the caller, This fundtion creates and setup the BD ring.

-
Parameters
- - - - - - -
RingPtris the BD ring instance to be worked on.
PhysAddris the physical base address of application memory region.
VirtAddris the virtual base address of the application memory region.If address translation is not being utilized, then VirtAddr should be equivalent to PhysAddr.
Alignmentgoverns the byte alignment of individual BDs. This function will enforce a minimum alignment of XAXIDMA_BD_MINIMUM_ALIGNMENT bytes with no maximum as long as it is specified as a power of 2.
BdCountis the number of BDs to setup in the application memory region. It is assumed the region is large enough to contain the BDs.Refer to the "SGDMA Ring Creation" section in xaxidma.h for more information. The minimum valid value for this parameter is 1.
-
-
-
Returns
    -
  • XST_SUCCESS if initialization was successful
      -
    • XST_NO_FEATURE if the provided instance is a non SGDMA type of DMA channel.
    • -
    -
  • -
  • XST_INVALID_PARAM under any of the following conditions: 1) BdCount is not positive
  • -
-
-

2) PhysAddr and/or VirtAddr are not aligned to the given Alignment parameter;

-

3) Alignment parameter does not meet minimum requirements or is not a power of 2 value.

-
    -
  • XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans over address 0x00000000 in virtual address space.
  • -
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::AllCnt, XAxiDma_BdRing::BdaRestart, XAxiDma_BdRing::FirstBdAddr, XAxiDma_BdRing::FirstBdPhysAddr, XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::FreeHead, XAxiDma_BdRing::HasStsCntrlStrm, XAxiDma_BdRing::HwCnt, XAxiDma_BdRing::HwHead, XAxiDma_BdRing::HwTail, XAxiDma_BdRing::LastBdAddr, XAxiDma_BdRing::Length, XAxiDma_BdRing::PostCnt, XAxiDma_BdRing::PostHead, XAxiDma_BdRing::PreCnt, XAxiDma_BdRing::PreHead, XAxiDma_BdRing::RunState, XAxiDma_BdRing::Separation, XAXIDMA_BD_ADDRLEN_OFFSET, XAXIDMA_BD_HAS_DRE_OFFSET, XAXIDMA_BD_HAS_DRE_SHIFT, XAXIDMA_BD_HAS_STSCNTRL_OFFSET, XAXIDMA_BD_MINIMUM_ALIGNMENT, XAXIDMA_BD_NDESC_MSB_OFFSET, XAXIDMA_BD_NDESC_OFFSET, XAxiDma_BdWrite, and XAXIDMA_DESC_LSB_MASK.

- -
-
- -
-
- - - - - - - - -
void XAxiDma_BdRingDumpRegs (XAxiDma_BdRingRingPtr)
-
- -

#include <xaxidma_bdring.c>

- -

Dump the registers for a channel.

-
Parameters
- - -
RingPtris a pointer to the descriptor ring to be worked on.
-
-
-
Returns
None
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::RingIndex, XAXIDMA_CDESC_OFFSET, XAXIDMA_CR_OFFSET, XAxiDma_ReadReg, XAXIDMA_RX_CDESC0_OFFSET, XAXIDMA_RX_NDESC_OFFSET, XAXIDMA_RX_TDESC0_OFFSET, XAXIDMA_SR_OFFSET, and XAXIDMA_TDESC_OFFSET.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingFree (XAxiDma_BdRingRingPtr,
int NumBd,
XAxiDma_BdBdSetPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Frees a set of BDs that had been previously retrieved with XAxiDma_BdRingFromHw().

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
NumBdis the number of BDs to free.
BdSetPtris the head of a list of BDs returned by XAxiDma_BdRingFromHw().
-
-
-
Returns
    -
  • XST_SUCCESS if the set of BDs was freed.
  • -
  • XST_INVALID_PARAM if NumBd is negative
  • -
  • XST_DMA_SG_LIST_ERROR if this function was called out of sequence with XAxiDma_BdRingFromHw().
  • -
-
-
Note
This function should not be preempted by another XAxiDma function call that modifies the BD space. It is the caller's responsibility to ensure mutual exclusion.
-

This function can be used only when DMA is in SG mode

- -

References XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::PostCnt, and XAxiDma_BdRing::PostHead.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingFromHw (XAxiDma_BdRingRingPtr,
int BdLimit,
XAxiDma_Bd ** BdSetPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Returns a set of BD(s) that have been processed by hardware.

-

The returned BDs may be examined by the application to determine the outcome of the DMA transactions. Once the BDs have been examined, the application must call XAxiDma_BdRingFree() in the same order which they were retrieved here.

-

Example:

-
-       NumBd = XAxiDma_BdRingFromHw(MyRingPtr, XAXIDMA_ALL_BDS, &MyBdSet);
       if (NumBd == 0)
-       {
-          // hardware has nothing ready for us yet
-       }
       CurBd = MyBdSet;
-       for (i=0; i<NumBd; i++)
-       {
-          // Examine CurBd for post processing.....
          // Onto next BD
-          CurBd = XAxiDma_BdRingNext(MyRingPtr, CurBd);
-       }
       XAxiDma_BdRingFree(MyRingPtr, NumBd, MyBdSet); // Return the list
-

A more advanced use of this function may allocate multiple sets of BDs. They must be retrieved from hardware and freed in the correct sequence:

-       // Legal
-       XAxiDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
       // Legal
-       XAxiDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
-       XAxiDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
-       XAxiDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
       // Not legal
-       XAxiDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
-       XAxiDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
-       XAxiDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
-       XAxiDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
-

If hardware has partially completed a packet spanning multiple BDs, then none of the BDs for that packet will be included in the results.

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
BdLimitis the maximum number of BDs to return in the set. Use XAXIDMA_ALL_BDS to return all BDs that have been processed.
BdSetPtris an output parameter, it points to the first BD available for examination.
-
-
-
Returns
The number of BDs processed by hardware. A value of 0 indicates that no data is available. No more than BdLimit BDs will be returned.
-
Note
Treat BDs returned by this function as read-only.
-

This function should not be preempted by another XAxiDma ring function call that modifies the BD space. It is the caller's responsibility to provide a mutual exclusion mechanism.

-

This function can be used only when DMA is in SG mode

- -

References XAxiDma_BdRing::HwCnt, XAxiDma_BdRing::HwHead, XAxiDma_BdRing::HwTail, XAxiDma_BdRing::IsRxChannel, XAxiDma_BdRing::PostCnt, XAXIDMA_BD_CTRL_LEN_OFFSET, XAXIDMA_BD_CTRL_TXEOF_MASK, XAXIDMA_BD_STS_COMPLETE_MASK, XAXIDMA_BD_STS_OFFSET, XAXIDMA_BD_STS_RXEOF_MASK, XAxiDma_BdRead, and XAxiDma_BdRingNext.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
void XAxiDma_BdRingGetCoalesce (XAxiDma_BdRingRingPtr,
u32 * CounterPtr,
u32 * TimerPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Retrieve current interrupt coalescing parameters from the given descriptor ring channel.

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
CounterPtrpoints to a memory location where the current packet counter will be written.
TimerPtrpoints to a memory location where the current waitbound timer will be written.
-
-
-
Returns
The passed in parameters, CounterPtr and TimerPtr, holds the references to the return values.
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::ChanBase, XAXIDMA_COALESCE_MASK, XAXIDMA_CR_OFFSET, XAXIDMA_DELAY_MASK, and XAxiDma_ReadReg.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingSetCoalesce (XAxiDma_BdRingRingPtr,
u32 Counter,
u32 Timer 
)
-
- -

#include <xaxidma_bdring.c>

- -

Set interrupt coalescing parameters for the given descriptor ring channel.

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
Countersets the packet counter on the channel. Valid range is
    -
  • 1..255.
  • -
  • XAXIDMA_NO_CHANGE to leave this setting unchanged.
  • -
-
Timersets the waitbound timer on the channel. Valid range is
    -
  • 0..255.
  • -
-
-
-
-
    -
  • XAXIDMA_NO_CHANGE to leave this setting unchanged. Each unit depend on hardware building parameter C_DLYTMR_RESOLUTION,which is in the range from 0 to 100,000 clock cycles. A value of 0 disables the delay interrupt.
  • -
-
Returns
    -
  • XST_SUCCESS if interrupt coalescing settings updated
  • -
  • XST_FAILURE if Counter or Timer parameters are out of range
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::ChanBase, XAXIDMA_COALESCE_MASK, XAXIDMA_CR_OFFSET, XAXIDMA_DELAY_MASK, XAxiDma_ReadReg, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - -
int XAxiDma_BdRingStart (XAxiDma_BdRingRingPtr)
-
- -

#include <xaxidma_bdring.c>

- -

Start a DMA channel, updates current descriptors and Allow DMA transactions to commence on a given channel if descriptors are ready to be processed.

-

After a DMA channel is started, it is not halted, and it is idle (no active DMA transfers).

-
Parameters
- - -
RingPtris the Channel instance to be worked on
-
-
-
Returns
    -
  • XST_SUCCESS upon success
  • -
  • XST_DMA_ERROR if no valid BD available to put into current BD register
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_StartBdRingHw(), and XAxiDma_UpdateBdRingCDesc().

- -

Referenced by XAxiDma_Resume().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingToHw (XAxiDma_BdRingRingPtr,
int NumBd,
XAxiDma_BdBdSetPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Enqueue a set of BDs to hardware that were previously allocated by XAxiDma_BdRingAlloc().

-

Once this function returns, the argument BD set goes under hardware control. Changes to these BDs should be held until they are finished by hardware to avoid data corruption and system instability.

-

For transmit, the set will be rejected if the last BD of the set does not mark the end of a packet or the first BD does not mark the start of a packet.

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
NumBdis the number of BDs in the set.
BdSetPtris the first BD of the set to commit to hardware.
-
-
-
Returns
    -
  • XST_SUCCESS if the set of BDs was accepted and enqueued to hardware
  • -
  • XST_INVALID_PARAM if passed in NumBd is negative
  • -
  • XST_FAILURE if the set of BDs was rejected because the first BD does not have its start-of-packet bit set, or the last BD does not have its end-of-packet bit set, or any one of the BDs has 0 length.
  • -
  • XST_DMA_SG_LIST_ERROR if this function was called out of sequence with XAxiDma_BdRingAlloc()
  • -
-
-
Note
This function should not be preempted by another XAxiDma ring function call that modifies the BD space. It is the caller's responsibility to provide a mutual exclusion mechanism.
-

This function can be used only when DMA is in SG mode

- -

References XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::HwCnt, XAxiDma_BdRing::HwTail, XAxiDma_BdRing::IsRxChannel, XAxiDma_BdRing::PreCnt, XAxiDma_BdRing::PreHead, XAxiDma_BdRing::RingIndex, XAxiDma_BdRing::RunState, XAXIDMA_BD_CTRL_LEN_OFFSET, XAXIDMA_BD_CTRL_TXEOF_MASK, XAXIDMA_BD_CTRL_TXSOF_MASK, XAXIDMA_BD_STS_COMPLETE_MASK, XAXIDMA_BD_STS_OFFSET, XAxiDma_BdGetCtrl, XAxiDma_BdGetLength, XAxiDma_BdGetSts, XAxiDma_BdRead, XAxiDma_BdRingNext, XAxiDma_BdWrite, XAXIDMA_DESC_LSB_MASK, XAXIDMA_RX_NDESC_OFFSET, XAXIDMA_RX_TDESC0_MSB_OFFSET, XAXIDMA_RX_TDESC0_OFFSET, XAXIDMA_TDESC_MSB_OFFSET, XAXIDMA_TDESC_OFFSET, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdRingUnAlloc (XAxiDma_BdRingRingPtr,
int NumBd,
XAxiDma_BdBdSetPtr 
)
-
- -

#include <xaxidma_bdring.c>

- -

Fully or partially undo an XAxiDma_BdRingAlloc() operation.

-

Use this function if all the BDs allocated by XAxiDma_BdRingAlloc() could not be transferred to hardware with XAxiDma_BdRingToHw().

-

This function releases the BDs after they have been allocated but before they have been given to hardware.

-

This function is not the same as XAxiDma_BdRingFree(). The Free function returns BDs to the free list after they have been processed by hardware, while UnAlloc returns them before being processed by hardware.

-

There are two scenarios where this function can be used. Full UnAlloc or Partial UnAlloc. A Full UnAlloc means all the BDs Alloc'd will be returned:

-
-   Status = XAxiDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
-       ...
-       ...
-   if (Error)
-   {
-       Status = XAxiDma_BdRingUnAlloc(MyRingPtr, 10, &BdPtr);
-   }
-

A partial UnAlloc means some of the BDs Alloc'd will be returned:

-
-   Status = XAxiDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
-   BdsLeft = 10;
-   CurBdPtr = BdPtr;
   while (BdsLeft)
-   {
-      if (Error)
-      {
-         Status = XAxiDma_BdRingUnAlloc(MyRingPtr, BdsLeft, CurBdPtr);
-      }
      CurBdPtr = XAxiDma_BdRingNext(MyRingPtr, CurBdPtr);
-      BdsLeft--;
-   }
-

A partial UnAlloc must include the last BD in the list that was Alloc'd.

-
Parameters
- - - - -
RingPtris a pointer to the descriptor ring instance to be worked on.
NumBdis the number of BDs to unallocate
BdSetPtrpoints to the first of the BDs to be returned.
-
-
-
Returns
    -
  • XST_SUCCESS if the BDs were unallocated.
  • -
  • XST_INVALID_PARAM if passed in NumBd is negative
  • -
  • XST_FAILURE if NumBd parameter was greater that the number of BDs in the preprocessing state.
  • -
-
-
Note
This function should not be preempted by another XAxiDma ring function call that modifies the BD space. It is the caller's responsibility to provide a mutual exclusion mechanism.
-

This function can be used only when DMA is in SG mode

- -

References XAxiDma_BdRing::FreeCnt, XAxiDma_BdRing::FreeHead, and XAxiDma_BdRing::PreCnt.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdSetAppWord (XAxiDma_BdBdPtr,
int Offset,
u32 Word 
)
-
- -

#include <xaxidma_bd.c>

- -

Set the APP word at the specified APP word offset for a BD.

-
Parameters
- - - - -
BdPtris the BD to operate on.
Offsetis the offset inside the APP word, it is valid from 0 to 4
Wordis the value to set
-
-
-
Returns
    -
  • XST_SUCCESS for success
  • -
  • XST_INVALID_PARAM under following error conditions: 1) StsCntrlStrm is not built in hardware 2) Offset is not in valid range
  • -
-
-
Note
If the hardware build has C_SG_USE_STSAPP_LENGTH set to 1, then the last APP word, XAXIDMA_LAST_APPWORD, must have non-zero value when AND with 0x7FFFFF. Not doing so will cause the hardware to stall. This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_HAS_STSCNTRL_OFFSET, XAXIDMA_BD_USR0_OFFSET, XAxiDma_BdRead, and XAxiDma_BdWrite.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
u32 XAxiDma_BdSetBufAddr (XAxiDma_BdBdPtr,
UINTPTR Addr 
)
-
- -

#include <xaxidma_bd.c>

- -

Set the BD's buffer address.

-
Parameters
- - - -
BdPtris the BD to operate on
Addris the address to set
-
-
-
Returns
    -
  • XST_SUCCESS if buffer address set successfully
  • -
  • XST_INVALID_PARAM if hardware has no DRE and address is not aligned
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_ADDRLEN_OFFSET, XAXIDMA_BD_BUFA_MSB_OFFSET, XAXIDMA_BD_BUFA_OFFSET, XAXIDMA_BD_HAS_DRE_MASK, XAXIDMA_BD_HAS_DRE_OFFSET, XAXIDMA_BD_WORDLEN_MASK, XAxiDma_BdRead, and XAxiDma_BdWrite.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
u32 XAxiDma_BdSetBufAddrMicroMode (XAxiDma_BdBdPtr,
UINTPTR Addr 
)
-
- -

#include <xaxidma_bd.c>

- -

Set the BD's buffer address when configured for Micro Mode.

-

The buffer address should be 4K aligned.

-
Parameters
- - - -
BdPtris the BD to operate on
Addris the address to set
-
-
-
Returns
    -
  • XST_SUCCESS if buffer address set successfully
  • -
  • XST_INVALID_PARAM if hardware has no DRE and address is not aligned
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_ADDRLEN_OFFSET, XAXIDMA_BD_BUFA_MSB_OFFSET, XAXIDMA_BD_BUFA_OFFSET, XAxiDma_BdRead, XAxiDma_BdWrite, and XAXIDMA_MICROMODE_MIN_BUF_ALIGN.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
void XAxiDma_BdSetCtrl (XAxiDma_BdBdPtr,
u32 Data 
)
-
- -

#include <xaxidma_bd.c>

- -

Set the control bits for a BD.

-
Parameters
- - - -
BdPtris the BD to operate on.
Datais the bit value to set
-
-
-
Returns
None
-
Note
This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_CTRL_ALL_MASK, XAXIDMA_BD_CTRL_LEN_OFFSET, XAxiDma_BdRead, and XAxiDma_BdWrite.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_BdSetLength (XAxiDma_BdBdPtr,
u32 LenBytes,
u32 LengthMask 
)
-
- -

#include <xaxidma_bd.c>

- -

Set the length field for the given BD.

-

Length has to be non-zero and less than LengthMask.

-

For TX channels, the value passed in should be the number of bytes to transmit from the TX buffer associated with the given BD.

-

For RX channels, the value passed in should be the size of the RX buffer associated with the given BD in bytes. This is to notify the RX channel the capability of the RX buffer to avoid buffer overflow.

-

The actual receive length can be equal or smaller than the specified length. The actual transfer length will be updated by the hardware in the XAXIDMA_BD_STS_OFFSET word in the BD.

-
Parameters
- - - - -
BdPtris the BD to operate on.
LenBytesis the requested transfer length
LengthMaskis the maximum transfer length
-
-
-
Returns
    -
  • XST_SUCCESS for success
  • -
  • XST_INVALID_PARAM for invalid BD length
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAXIDMA_BD_CTRL_LEN_OFFSET, XAxiDma_BdRead, and XAxiDma_BdWrite.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
u32 XAxiDma_Busy (XAxiDmaInstancePtr,
int Direction 
)
-
- -

#include <xaxidma.c>

- -

This function checks whether specified DMA channel is busy.

-
Parameters
- - - -
InstancePtris the driver instance we are working on
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
- TRUE if channel is busy
    -
  • FALSE if channel is idle
  • -
-
-
Note
None.
- -

References XAXIDMA_IDLE_MASK, XAxiDma_ReadReg, XAXIDMA_RX_OFFSET, and XAXIDMA_SR_OFFSET.

- -

Referenced by XAxiDma_SimpleTransfer().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
int XAxiDma_CfgInitialize (XAxiDmaInstancePtr,
XAxiDma_ConfigConfig 
)
-
- -

#include <xaxidma.c>

- -

This function initializes a DMA engine.

-

This function must be called prior to using a DMA engine. Initializing a engine includes setting up the register base address, setting up the instance data, and ensuring the hardware is in a quiescent state.

-
Parameters
- - - -
InstancePtris a pointer to the DMA engine instance to be worked on.
Configis a pointer to an XAxiDma_Config structure. It contains the information about the hardware build, including base address,and whether status control stream (StsCntrlStrm), MM2S and S2MM are included in the build.
-
-
-
Returns
    -
  • XST_SUCCESS for successful initialization
  • -
  • XST_INVALID_PARAM if pointer to the configuration structure is NULL
  • -
  • XST_DMA_ERROR if reset operation failed at the end of initialization
  • -
-
-
Note
We assume the hardware building tool will check and error out for a hardware build that has no transfer channels.
- -

References XAxiDma::AddrWidth, XAxiDma_Config::AddrWidth, XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::HasStsCntrlStrm, XAxiDma_BdRing::IsRxChannel, XAxiDma_BdRing::RingIndex, XAxiDma_BdRing::RunState, XAxiDma_Reset(), XAxiDma_ResetIsDone(), XAXIDMA_RX_OFFSET, and XAXIDMA_TX_OFFSET.

- -
-
- -
-
- - - - - - - - -
void XAxiDma_DumpBd (XAxiDma_BdBdPtr)
-
-
- -
-
- - - - - - - - -
XAxiDma_Config * XAxiDma_LookupConfig (u32 DeviceId)
-
- -

#include <xaxidma.h>

- -

Look up the hardware configuration for a device instance.

-
Parameters
- - -
DeviceIdis the unique device ID of the device to lookup for
-
-
-
Returns
The configuration structure for the device. If the device ID is not found,a NULL pointer is returned.
-
Note
None
- -
-
- -
-
- - - - - - - - -
int XAxiDma_Pause (XAxiDmaInstancePtr)
-
- -

#include <xaxidma.c>

- -

Pause DMA transactions on both channels.

-

If the engine is running and doing transfers, this function does not stop the DMA transactions immediately, because then hardware will throw away our previously queued transfers. All submitted transfers will finish. Transfers submitted after this function will not start until XAxiDma_BdRingStart() or XAxiDma_Resume() is called.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
    -
  • XST_SUCCESS if successful
  • -
  • XST_NOT_SGDMA, if the driver instance is not initialized
  • -
-
-
Note
None
- -

References XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::RunState, XAXIDMA_CR_OFFSET, XAXIDMA_CR_RUNSTOP_MASK, XAxiDma_GetRxIndexRing, XAxiDma_GetTxRing, XAxiDma_HasSg, XAxiDma_ReadReg, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - -
void XAxiDma_Reset (XAxiDmaInstancePtr)
-
- -

#include <xaxidma.c>

- -

Reset both TX and RX channels of a DMA engine.

-

Reset one channel resets the whole AXI DMA engine.

-

Any DMA transaction in progress will finish gracefully before engine starts reset. Any other transactions that have been submitted to hardware will be discarded by the hardware.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
None
-
Note
After the reset:
    -
  • All interrupts are disabled.
  • -
  • Engine is halted
  • -
-
- -

References XAxiDma_BdRing::RunState, XAxiDma_BdRingSnapShotCurrBd, XAXIDMA_CR_OFFSET, XAXIDMA_CR_RESET_MASK, XAxiDma_GetRxIndexRing, XAxiDma_GetTxRing, XAxiDma_HasSg, XAXIDMA_RX_OFFSET, XAXIDMA_TX_OFFSET, and XAxiDma_WriteReg.

- -

Referenced by XAxiDma_CfgInitialize(), and XAxiDma_Selftest().

- -
-
- -
-
- - - - - - - - -
int XAxiDma_ResetIsDone (XAxiDmaInstancePtr)
-
- -

#include <xaxidma.c>

- -

Check whether reset is done.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
    -
  • 1 if reset is done.
  • -
-
-
    -
  • 0 if reset is not done
  • -
-
Note
None
- -

References XAxiDma_BdRing::ChanBase, XAXIDMA_CR_OFFSET, XAXIDMA_CR_RESET_MASK, XAxiDma_GetRxRing, XAxiDma_GetTxRing, and XAxiDma_ReadReg.

- -

Referenced by XAxiDma_CfgInitialize(), and XAxiDma_Selftest().

- -
-
- -
-
- - - - - - - - -
int XAxiDma_Resume (XAxiDmaInstancePtr)
-
- -

#include <xaxidma.c>

- -

Resume DMA transactions on both channels.

-
Parameters
- - -
InstancePtris a pointer to the DMA engine instance to be worked on.
-
-
-
Returns
    -
  • XST_SUCCESS for success
  • -
  • XST_NOT_SGDMA if the driver instance has not been initialized
  • -
  • XST_DMA_ERROR if one of the channels fails to start
  • -
-
-
Note
None
- -

References XAxiDma_BdRing::RunState, XAxiDma_BdRingStart(), XAxiDma_GetRxIndexRing, XAxiDma_GetTxRing, and XAxiDma_HasSg.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_SelectCyclicMode (XAxiDmaInstancePtr,
int Direction,
int Select 
)
-
- -

#include <xaxidma.c>

- -

This function Enable or Disable Cyclic Mode Feature.

-
Parameters
- - - -
InstancePtris the driver instance we are working on
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA. Select is the option to enable (TRUE) or disable (FALSE).
  • -
-
-
-
-
Returns
- XST_SUCCESS for success
-
Note
None.
- -

References XAXIDMA_CR_CYCLIC_MASK, XAXIDMA_CR_OFFSET, XAxiDma_ReadReg, XAXIDMA_RX_OFFSET, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int XAxiDma_SelectKeyHole (XAxiDmaInstancePtr,
int Direction,
int Select 
)
-
- -

#include <xaxidma.c>

- -

This function Enable or Disable KeyHole Feature.

-
Parameters
- - - -
InstancePtris the driver instance we are working on
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA. Select is the option to enable (TRUE) or disable (FALSE).
  • -
-
-
-
-
Returns
- XST_SUCCESS for success
-
Note
None.
- -

References XAXIDMA_CR_KEYHOLE_MASK, XAXIDMA_CR_OFFSET, XAxiDma_ReadReg, XAXIDMA_RX_OFFSET, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - -
int XAxiDma_Selftest (XAxiDmaInstancePtr)
-
- -

#include <xaxidma.h>

- -

Runs a self-test on the driver/device.

-

This test perform a reset of the DMA device and checks the device is coming out of reset or not

-
Parameters
- - -
InstancePtris a pointer to the XAxiDma instance.
-
-
-
Returns
    -
  • XST_SUCCESS if self-test was successful
  • -
-
-
    -
  • XST_FAILURE if the device is not coming out of reset.
  • -
-
Note
None.
- -

References XAxiDma_Reset(), and XAxiDma_ResetIsDone().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 XAxiDma_SimpleTransfer (XAxiDmaInstancePtr,
UINTPTR BuffAddr,
u32 Length,
int Direction 
)
-
- -

#include <xaxidma.c>

- -

This function does one simple transfer submission.

-

It checks in the following sequence:

    -
  • if engine is busy, cannot submit
  • -
  • if engine is in SG mode , cannot submit
  • -
-
Parameters
- - - - - -
InstancePtris the pointer to the driver instance
BuffAddris the address of the source/destination buffer
Lengthis the length of the transfer
Directionis DMA transfer direction, valid values are
    -
  • XAXIDMA_DMA_TO_DEVICE.
  • -
  • XAXIDMA_DEVICE_TO_DMA.
  • -
-
-
-
-
Returns
    -
  • XST_SUCCESS for success of submission
  • -
  • XST_FAILURE for submission failure, maybe caused by: Another simple transfer is still going
  • -
  • XST_INVALID_PARAM if:Length out of valid range [1:8M] Or, address not aligned when DRE is not built in
  • -
-
-
Note
This function is used only when system is configured as Simple mode.
- -

References XAxiDma::AddrWidth, XAxiDma_BdRing::ChanBase, XAXIDMA_BUFFLEN_OFFSET, XAxiDma_Busy(), XAXIDMA_CR_OFFSET, XAXIDMA_CR_RUNSTOP_MASK, XAXIDMA_DESTADDR_MSB_OFFSET, XAXIDMA_DESTADDR_OFFSET, XAXIDMA_HALTED_MASK, XAxiDma_HasSg, XAXIDMA_MICROMODE_MIN_BUF_ALIGN, XAxiDma_ReadReg, XAXIDMA_SR_OFFSET, XAXIDMA_SRCADDR_MSB_OFFSET, XAXIDMA_SRCADDR_OFFSET, and XAxiDma_WriteReg.

- -
-
- -
-
- - - - - - - - -
int XAxiDma_StartBdRingHw (XAxiDma_BdRingRingPtr)
-
- -

#include <xaxidma_bdring.c>

- -

Start a DMA channel and Allow DMA transactions to commence on a given channel if descriptors are ready to be processed.

-

After a DMA channel is started, it is not halted, and it is idle (no active DMA transfers).

-
Parameters
- - -
RingPtris the Channel instance to be worked on
-
-
-
Returns
    -
  • XST_SUCCESS upon success
  • -
  • XST_DMA_ERROR if no valid BD available to put into current BD register
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::HwCnt, XAxiDma_BdRing::HwTail, XAxiDma_BdRing::IsRxChannel, XAxiDma_BdRing::RingIndex, XAxiDma_BdRing::RunState, XAXIDMA_BD_STS_COMPLETE_MASK, XAXIDMA_BD_STS_OFFSET, XAxiDma_BdRead, XAxiDma_BdRingHwIsStarted, XAXIDMA_CR_OFFSET, XAXIDMA_CR_RUNSTOP_MASK, XAXIDMA_DESC_LSB_MASK, XAxiDma_ReadReg, XAXIDMA_RX_NDESC_OFFSET, XAXIDMA_RX_TDESC0_MSB_OFFSET, XAXIDMA_RX_TDESC0_OFFSET, XAXIDMA_TDESC_MSB_OFFSET, XAXIDMA_TDESC_OFFSET, and XAxiDma_WriteReg.

- -

Referenced by XAxiDma_BdRingStart().

- -
-
- -
-
- - - - - - - - -
int XAxiDma_UpdateBdRingCDesc (XAxiDma_BdRingRingPtr)
-
- -

#include <xaxidma_bdring.c>

- -

Update Current Descriptor.

-
Parameters
- - -
RingPtris the Channel instance to be worked on
-
-
-
Returns
    -
  • XST_SUCCESS upon success
  • -
  • XST_DMA_ERROR if no valid BD available to put into current BD register
  • -
-
-
Note
This function can be used only when DMA is in SG mode
- -

References XAxiDma_BdRing::AllCnt, XAxiDma_BdRing::BdaRestart, XAxiDma_BdRing::ChanBase, XAxiDma_BdRing::IsRxChannel, XAxiDma_BdRing::RingIndex, XAxiDma_BdRing::RunState, XAxiDma_BdHwCompleted, XAxiDma_BdRingHwIsStarted, XAxiDma_BdRingNext, XAXIDMA_CDESC_MSB_OFFSET, XAXIDMA_CDESC_OFFSET, XAXIDMA_DESC_LSB_MASK, XAXIDMA_RX_CDESC0_MSB_OFFSET, XAXIDMA_RX_CDESC0_OFFSET, XAXIDMA_RX_NDESC_OFFSET, and XAxiDma_WriteReg.

- -

Referenced by XAxiDma_BdRingStart().

- -
-
-
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/index.html b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/index.html deleted file mode 100644 index b6e8d3690..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/index.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - -axidma_v9_0: Main Page - - - - - - - -
-
- - - - - - - -
-
axidma_v9_0 -
-
Xilinx SDK Drivers API Documentation
-
-
- - - -
-
-
-
axidma_v9_0 Documentation
-
-
-

This is the driver API for the AXI DMA engine.For a full description of DMA features, please see the hardware spec. This driver supports the following features:

-
    -
  • Scatter-Gather DMA (SGDMA)
  • -
  • Simple DMA
  • -
  • Interrupts
  • -
  • Programmable interrupt coalescing for SGDMA
  • -
  • APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA engine
  • -
-

Simple DMA

-

Simple DMA allows the application to define a single transaction between DMA and Device. It has two channels: one from the DMA to Device and the other from Device to DMA. Application has to set the buffer address and length fields to initiate the transfer in respective channel.

-

Transactions

-

The object used to describe a transaction is referred to as a Buffer Descriptor (BD). Buffer descriptors are allocated in the user application. The user application needs to set buffer address, transfer length, and control information for this transfer. The control information includes SOF and EOF. Definition of those masks are in xaxidma_hw.h

-

Scatter-Gather DMA

-

SGDMA allows the application to define a list of transactions in memory which the hardware will process without further application intervention. During this time, the application is free to continue adding more work to keep the Hardware busy.

-

User can check for the completion of transactions through polling the hardware, or interrupts.

-

SGDMA processes whole packets. A packet is defined as a series of data bytes that represent a message. SGDMA allows a packet of data to be broken up into one or more transactions. For example, take an Ethernet IP packet which consists of a 14 byte header followed by a 1 or more bytes of payload. With SGDMA, the application may point a BD to the header and another BD to the payload, then transfer them as a single message. This strategy can make a TCP/IP stack more efficient by allowing it to keep packet header and data in different memory regions instead of assembling packets into contiguous blocks of memory.

-

BD Ring Management

-

BD rings are shared by the software and the hardware.

-

The hardware expects BDs to be setup as a linked list. The DMA hardware walks through the list by following the next pointer field of a completed BD. The hardware stops processing when the just completed BD is the same as the BD specified in the Tail Ptr register in the hardware.

-

The last BD in the ring is linked to the first BD in the ring.

-

All BD management are done inside the driver. The user application should not directly modify the BD fields. Modifications to the BD fields should always go through the specific API functions.

-

Within the ring, the driver maintains four groups of BDs. Each group consists of 0 or more adjacent BDs:

-
    -
  • Free: The BDs that can be allocated by the application with XAxiDma_BdRingAlloc().
  • -
  • Pre-process: The BDs that have been allocated with XAxiDma_BdRingAlloc(). These BDs are under application control. The application modifies these BDs through driver API to prepare them for DMA transactions.
  • -
  • Hardware: The BDs that have been enqueued to hardware with XAxiDma_BdRingToHw(). These BDs are under hardware control and may be in a state of awaiting hardware processing, in process, or processed by hardware. It is considered an error for the application to change BDs while they are in this group. Doing so can cause data corruption and lead to system instability.
  • -
  • Post-process: The BDs that have been processed by hardware and have been extracted from the Hardware group with XAxiDma_BdRingFromHw(). These BDs are under application control. The application can check the transfer status of these BDs. The application use XAxiDma_BdRingFree() to put them into the Free group.
  • -
-

BDs are expected to transition in the following way for continuous DMA transfers:

        XAxiDma_BdRingAlloc()                   XAxiDma_BdRingToHw()
-  Free ------------------------> Pre-process ----------------------> Hardware
-                                                                     |
-   /|\                                                               |
-    |   XAxiDma_BdRingFree()                  XAxiDma_BdRingFromHw() |
-    +--------------------------- Post-process <----------------------+

When a DMA transfer is to be cancelled before enqueuing to hardware, application can return the requested BDs to the Free group using XAxiDma_BdRingUnAlloc(), as shown below:

        XAxiDma_BdRingUnAlloc()
-  Free <----------------------- Pre-process

The API provides functions for BD list traversal:

-

These functions should be used with care as they do not understand where one group ends and another begins.

-

SGDMA Descriptor Ring Creation

-

BD ring is created using XAxiDma_BdRingCreate(). The memory for the BD ring is allocated by the application, and it has to be contiguous. Physical address is required to setup the BD ring.

-

The applicaiton can use XAxiDma_BdRingMemCalc() to find out the amount of memory needed for a certain number of BDs. XAxiDma_BdRingCntCalc() can be used to find out how many BDs can be allocated for certain amount of memory.

-

A helper function, XAxiDma_BdRingClone(), can speed up the BD ring setup if the BDs have same types of controls, for example, SOF and EOF. After using the XAxiDma_BdRingClone(), the application only needs to setup the buffer address and transfer length. Note that certain BDs in one packet, for example, the first BD and the last BD, may need to setup special control information.

-

Descriptor Ring State Machine

-

There are two states of the BD ring:

-
    -
  • HALTED (H), where hardware is not running
  • -
  • NOT HALTED (NH), where hardware is running
  • -
-

The following diagram shows the state transition for the DMA engine:

-
-  _____ XAxiDma_StartBdRingHw(), or XAxiDma_BdRingStart(),   ______
-  |   |               or XAxiDma_Resume()                    |    |
-  | H |----------------------------------------------------->| NH |
-  |   |<-----------------------------------------------------|    |
-  -----   XAxiDma_Pause() or XAxiDma_Reset()                 ------
-

Interrupt Coalescing

-

SGDMA provides control over the frequency of interrupts through interrupt coalescing. The DMA engine provides two ways to tune the interrupt coalescing:

-
    -
  • The packet threshold counter. Interrupt will fire once the programmable number of packets have been processed by the engine.
  • -
  • The packet delay timer counter. Interrupt will fire once the programmable amount of time has passed after processing the last packet, and no new packets to process. Note that the interrupt will only fire if at least one packet has been processed.
  • -
-

Interrupt

-

Interrupts are handled by the user application. Each DMA channel has its own interrupt ID. The driver provides APIs to enable/disable interrupt, and tune the interrupt frequency regarding to packet processing frequency.

-

Software Initialization

-

To use the Simple mode DMA engine for transfers, the following setup is required:

-
    -
  • DMA Initialization using XAxiDma_CfgInitialize() function. This step initializes a driver instance for the given DMA engine and resets the engine.
  • -
  • Enable interrupts if chosen to use interrupt mode. The application is responsible for setting up the interrupt system, which includes providing and connecting interrupt handlers and call back functions, before enabling the interrupts.
  • -
  • Set the buffer address and length field in respective channels to start the DMA transfer
  • -
-

To use the SG mode DMA engine for transfers, the following setup are required:

-
    -
  • DMA Initialization using XAxiDma_CfgInitialize() function. This step initializes a driver instance for the given DMA engine and resets the engine.
  • -
  • BD Ring creation. A BD ring is needed per DMA channel and can be built by calling XAxiDma_BdRingCreate().
  • -
  • Enable interrupts if chose to use interrupt mode. The application is responsible for setting up the interrupt system, which includes providing and connecting interrupt handlers and call back functions, before enabling the interrupts.
  • -
  • Start a DMA transfer: Call XAxiDma_BdRingStart() to start a transfer for the first time or after a reset, and XAxiDma_BdRingToHw() if the channel is already started. Calling XAxiDma_BdRingToHw() when a DMA channel is not running will not put the BDs to the hardware, and the BDs will be processed later when the DMA channel is started through XAxiDma_BdRingStart().
  • -
-

How to start DMA transactions

-

The user application uses XAxiDma_BdRingToHw() to submit BDs to the hardware to start DMA transfers.

-

For both channels, if the DMA engine is currently stopped (using XAxiDma_Pause()), the newly added BDs will be accepted but not processed until the DMA engine is started, using XAxiDma_BdRingStart(), or resumed, using XAxiDma_Resume().

-

Software Post-Processing on completed DMA transactions

-

If the interrupt system has been set up and the interrupts are enabled, a DMA channels notifies the software about the completion of a transfer through interrupts. Otherwise, the user application can poll for completions of the BDs, using XAxiDma_BdRingFromHw() or XAxiDma_BdHwCompleted().

-
    -
  • Once BDs are finished by a channel, the application first needs to fetch them from the channel using XAxiDma_BdRingFromHw().
  • -
  • On the TX side, the application now could free the data buffers attached to those BDs as the data in the buffers has been transmitted.
  • -
  • On the RX side, the application now could use the received data in the buffers attached to those BDs.
  • -
  • For both channels, completed BDs need to be put back to the Free group using XAxiDma_BdRingFree(), so they can be used for future transactions.
  • -
  • On the RX side, it is the application's responsibility to have BDs ready to receive data at any time. Otherwise, the RX channel refuses to accept any data if it has no RX BDs.
  • -
-

Examples

-

We provide five examples to show how to use the driver API:

    -
  • One for SG interrupt mode (xaxidma_example_sg_intr.c), multiple BD/packets transfer
  • -
  • One for SG polling mode (xaxidma_example_sg_poll.c), single BD transfer.
  • -
  • One for SG polling mode (xaxidma_poll_multi_pkts.c), multiple BD/packets transfer
  • -
  • One for simple polling mode (xaxidma_example_simple_poll.c)
  • -
  • One for simple Interrupt mode (xaxidma_example_simple_intr.c)
  • -
-

Address Translation

-

All buffer addresses and BD addresses for the hardware are physical addresses. The user application is responsible to provide physical buffer address for the BD upon BD ring creation. The user application accesses BD through its virtual addess. The driver maintains the address translation between the physical and virtual address for BDs.

-

Cache Coherency

-

This driver expects all application buffers attached to BDs to be in cache coherent memory. If cache is used in the system, buffers for transmit MUST be flushed from the cache before passing the associated BD to this driver. Buffers for receive MUST be invalidated before accessing the data.

-

Alignment

-

For BDs:

-

Minimum alignment is defined by the constant XAXIDMA_BD_MINIMUM_ALIGNMENT. This is the smallest alignment allowed by both hardware and software for them to properly work.

-

If the descriptor ring is to be placed in cached memory, alignment also MUST be at least the processor's cache-line size. Otherwise, system instability occurs. For alignment larger than the cache line size, multiple cache line size alignment is required.

-

Aside from the initial creation of the descriptor ring (see XAxiDma_BdRingCreate()), there are no other run-time checks for proper alignment of BDs.

-

For application data buffers:

-

Application data buffers may reside on any alignment if DRE is built into the hardware. Otherwise, application data buffer must be word-aligned. The word is defined by XPAR_AXIDMA_0_M_AXIS_MM2S_TDATA_WIDTH for transmit and XPAR_AXIDMA_0_S_AXIS_S2MM_TDATA_WIDTH for receive.

-

For scatter gather transfers that have more than one BDs in the chain of BDs, Each BD transfer length must be multiple of word too. Otherwise, internal error happens in the hardware.

-

Error Handling

-

The DMA engine will halt on all error conditions. It requires the software to do a reset before it can start process new transfer requests.

-

Restart After Stopping

-

After the DMA engine has been stopped (through reset or reset after an error) the software keeps track of the current BD pointer when reset happens, and processing of BDs can be resumed through XAxiDma_BdRingStart().

-

Limitations

-

This driver does not have any mechanisms for mutual exclusion. It is up to the application to provide this protection.

-

Hardware Defaults & Exclusive Use

-

After the initialization or reset, the DMA engine is in the following default mode:

    -
  • All interrupts are disabled.
  • -
  • Interrupt coalescing counter is 1.
  • -
  • The DMA engine is not running (halted). Each DMA channel is started separately, using XAxiDma_StartBdRingHw() if no BDs are setup for transfer yet, or XAxiDma_BdRingStart() otherwise.
  • -
-

The driver has exclusive use of the registers and BDs. All accesses to the registers and BDs should go through the driver interface.

-

Debug Print

-

To see the debug print for the driver, please put "-DDEBUG" as the extra compiler flags in software platform settings. Also comment out the line in xdebug.h: "#undef DEBUG".

-

Changes From v1.00a

-

. We have changes return type for XAxiDma_BdSetBufAddr() from void to int . We added XAxiDma_LookupConfig() so that user does not need to look for the hardware settings anymore.

-
-MODIFICATION HISTORY:
Ver   Who  Date     Changes
------ ---- -------- -------------------------------------------------------
-1.00a jz   05/18/10 First release
-2.00a jz   08/10/10 Second release, added in xaxidma_g.c, xaxidma_sinit.c,
-                    updated tcl file, added xaxidma_porting_guide.h
-3.00a jz   11/22/10 Support IP core parameters change
-4.00a rkv  02/22/11 Added support for simple DMA mode
-      	      New API added for simple DMA mode are

    -
  • XAxiDma_Busy
  • -
  • XAxiDma_SimpleTransfer - New Macros added for simple DMA mode are
      -
    • XAxiDma_HasSg
    • -
    • XAxiDma_IntrEnable
    • -
    • XAxiDma_IntrGetEnabled
    • -
    • XAxiDma_IntrDisable
    • -
    • XAxiDma_IntrGetIrq
    • -
    • XAxiDma_IntrAckIrq -5.00a srt 08/25/11 Added support for memory barrier and modified - Cache Macros to have a common API for Microblaze - and Zynq. -6.00a srt 01/24/12 Added support for Multi-Channel DMA mode.
    • -
    -
  • -
-
Changed APIs:
-      		* XAxiDma_GetRxRing(InstancePtr, RingIndex)
-      		* XAxiDma_Start(XAxiDma * InstancePtr, int RingIndex)
-      		* XAxiDma_Started(XAxiDma * InstancePtr, int RingIndex)
-      		* XAxiDma_Pause(XAxiDma * InstancePtr, int RingIndex)
-      		* XAxiDma_Resume(XAxiDma * InstancePtr, int RingIndex)
-      		* XAxiDma_SimpleTransfer(XAxiDma *InstancePtr,
-       					u32 BuffAddr, u32 Length,
-      					int Direction, int RingIndex)
-      		* XAxiDma_StartBdRingHw(XAxiDma_BdRing * RingPtr,
-      				int RingIndex)
-      		* XAxiDma_BdRingStart(XAxiDma_BdRing * RingPtr,
-      					 int RingIndex)
-      		* XAxiDma_BdRingToHw(XAxiDma_BdRing * RingPtr,
-       			int NumBd, XAxiDma_Bd * BdSetPtr, int RingIndex)
-      		* XAxiDma_BdRingDumpRegs(XAxiDma_BdRing * RingPtr,
-      					 int RingIndex)
-      		* XAxiDma_BdRingSnapShotCurrBd(XAxiDma_BdRing * RingPtr,
-      					 int RingIndex)
-      		* XAxiDma_BdSetLength(XAxiDma_Bd *BdPtr,
-      				u32 LenBytes, u32 LengthMask)
-      		* XAxiDma_BdGetActualLength(BdPtr, LengthMask)
-      		* XAxiDma_BdGetLength(BdPtr, LengthMask)

    -
  • New APIs - * XAxiDma_SelectKeyHole(XAxiDma *InstancePtr, - int Direction, int Select) - * XAxiDma_UpdateBdRingCDesc(XAxiDma_BdRing * RingPtr, - int RingIndex) -7.00a srt 06/18/12 All the APIs changed in v6_00_a are reverted back for - backward compatibility. -
  • -
  • Changed the logic of MCDMA BD fields Set APIs, to - clear the field first and then set it. -7.02a srt 01/23/13 Replaced *_TDATA_WIDTH parameters to *_DATA_WIDTH - (CR 691867) - Updated DDR base address for IPI designs (CR 703656). -8.0 adk 19/12/13 Updated as per the New Tcl API's - srt 01/29/14 Added support for Micro DMA Mode and cyclic mode of - operations.
  • -
-
New APIs:
-      		* XAxiDma_SelectCyclicMode(XAxiDma *InstancePtr,
-      					int Direction, int Select)
-			* XAxiDma_BdSetBufAddrMicroMode(XAxiDma_Bd*, u32)
-8.1   adk  20/01/15  Added support for peripheral test. Created the self
-      	       test example to include it on peripheral test's(CR#823144).
-8.1   adk  29/01/15  Added the sefltest api (XAxiDma_Selftest) to the driver source files
-		      (xaxidma_selftest.c) and called this from the selftest example
-9.0 	adk  27/07/15  Added support for 64-bit Addressing.
-9.0   adk  19/08/15  Fixed CR#873125 DMA SG Mode example tests are failing on
-      	       HW in 2015.3.
 
- - - diff --git a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/jquery.js b/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/jquery.js deleted file mode 100644 index 1f4d0b47c..000000000 --- a/thirdparty/libxil/orig/axidma_v9_0/doc/html/api/jquery.js +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * jQuery JavaScript Library v1.7.1 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Mon Nov 21 21:11:03 2011 -0500 - */ -(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! - * jQuery UI 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! - * jQuery UI Widget 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */ -(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! - * jQuery UI Mouse 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */ -(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! - * jQuery hashchange event - v1.3 - 7/21/2010 - * http://benalman.com/projects/jquery-hashchange-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('