summaryrefslogtreecommitdiffstats
path: root/src/seastar/dpdk/lib/librte_eal/windows
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/seastar/dpdk/lib/librte_eal/windows
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/seastar/dpdk/lib/librte_eal/windows')
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/eal.c84
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/eal_debug.c19
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/eal_lcore.c100
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/eal_thread.c153
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h48
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/pthread.h27
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/regex.h90
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/rte_os.h52
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/sched.h46
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/sys/queue.h320
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/include/unistd.h12
-rw-r--r--src/seastar/dpdk/lib/librte_eal/windows/eal/meson.build20
12 files changed, 971 insertions, 0 deletions
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/eal.c b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal.c
new file mode 100644
index 000000000..ce460481f
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <io.h>
+#include <fcntl.h>
+#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <eal_thread.h>
+#include <eal_private.h>
+
+/* Address of global and public configuration */
+static struct rte_config rte_config;
+
+/* internal configuration (per-core) */
+struct lcore_config lcore_config[RTE_MAX_LCORE];
+
+/* Return a pointer to the configuration structure */
+struct rte_config *
+rte_eal_get_configuration(void)
+{
+ return &rte_config;
+}
+
+static int
+sync_func(void *arg __rte_unused)
+{
+ return 0;
+}
+
+static void
+rte_eal_init_alert(const char *msg)
+{
+ fprintf(stderr, "EAL: FATAL: %s\n", msg);
+ RTE_LOG(ERR, EAL, "%s\n", msg);
+}
+
+ /* Launch threads, called at application init(). */
+int
+rte_eal_init(int argc __rte_unused, char **argv __rte_unused)
+{
+ int i;
+
+ /* create a map of all processors in the system */
+ eal_create_cpu_map();
+
+ if (rte_eal_cpu_init() < 0) {
+ rte_eal_init_alert("Cannot detect lcores.");
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
+ eal_thread_init_master(rte_config.master_lcore);
+
+ RTE_LCORE_FOREACH_SLAVE(i) {
+
+ /*
+ * create communication pipes between master thread
+ * and children
+ */
+ if (_pipe(lcore_config[i].pipe_master2slave,
+ sizeof(char), _O_BINARY) < 0)
+ rte_panic("Cannot create pipe\n");
+ if (_pipe(lcore_config[i].pipe_slave2master,
+ sizeof(char), _O_BINARY) < 0)
+ rte_panic("Cannot create pipe\n");
+
+ lcore_config[i].state = WAIT;
+
+ /* create a thread for each lcore */
+ if (eal_thread_create(&lcore_config[i].thread_id) != 0)
+ rte_panic("Cannot create thread\n");
+ }
+
+ /*
+ * Launch a dummy function on all slave lcores, so that master lcore
+ * knows they are all ready when this function returns.
+ */
+ rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
+ rte_eal_mp_wait_lcore();
+ return 0;
+}
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_debug.c b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_debug.c
new file mode 100644
index 000000000..edcf257cc
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_debug.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <stdarg.h>
+#include <rte_log.h>
+
+ /* call abort(), it will generate a coredump if enabled */
+void
+__rte_panic(const char *funcname, const char *format, ...)
+{
+ va_list ap;
+
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+ va_end(ap);
+ abort();
+}
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_lcore.c b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_lcore.c
new file mode 100644
index 000000000..d39f348a3
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_lcore.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <stdint.h>
+
+#include <rte_common.h>
+
+/* global data structure that contains the CPU map */
+static struct _wcpu_map {
+ unsigned int total_procs;
+ unsigned int proc_sockets;
+ unsigned int proc_cores;
+ unsigned int reserved;
+ struct _win_lcore_map {
+ uint8_t socket_id;
+ uint8_t core_id;
+ } wlcore_map[RTE_MAX_LCORE];
+} wcpu_map = { 0 };
+
+/*
+ * Create a map of all processors and associated cores on the system
+ */
+void
+eal_create_cpu_map()
+{
+ wcpu_map.total_procs =
+ GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
+
+ LOGICAL_PROCESSOR_RELATIONSHIP lprocRel;
+ DWORD lprocInfoSize = 0;
+ BOOL ht_enabled = FALSE;
+
+ /* First get the processor package information */
+ lprocRel = RelationProcessorPackage;
+ /* Determine the size of buffer we need (pass NULL) */
+ GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+ wcpu_map.proc_sockets = lprocInfoSize / 48;
+
+ lprocInfoSize = 0;
+ /* Next get the processor core information */
+ lprocRel = RelationProcessorCore;
+ GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+ wcpu_map.proc_cores = lprocInfoSize / 48;
+
+ if (wcpu_map.total_procs > wcpu_map.proc_cores)
+ ht_enabled = TRUE;
+
+ /* Distribute the socket and core ids appropriately
+ * across the logical cores. For now, split the cores
+ * equally across the sockets.
+ */
+ unsigned int lcore = 0;
+ for (unsigned int socket = 0; socket <
+ wcpu_map.proc_sockets; ++socket) {
+ for (unsigned int core = 0;
+ core < (wcpu_map.proc_cores / wcpu_map.proc_sockets);
+ ++core) {
+ wcpu_map.wlcore_map[lcore]
+ .socket_id = socket;
+ wcpu_map.wlcore_map[lcore]
+ .core_id = core;
+ lcore++;
+ if (ht_enabled) {
+ wcpu_map.wlcore_map[lcore]
+ .socket_id = socket;
+ wcpu_map.wlcore_map[lcore]
+ .core_id = core;
+ lcore++;
+ }
+ }
+ }
+}
+
+/*
+ * Check if a cpu is present by the presence of the cpu information for it
+ */
+int
+eal_cpu_detected(unsigned int lcore_id)
+{
+ return (lcore_id < wcpu_map.total_procs);
+}
+
+/*
+ * Get CPU socket id for a logical core
+ */
+unsigned
+eal_cpu_socket_id(unsigned int lcore_id)
+{
+ return wcpu_map.wlcore_map[lcore_id].socket_id;
+}
+
+/*
+ * Get CPU socket id (NUMA node) for a logical core
+ */
+unsigned
+eal_cpu_core_id(unsigned int lcore_id)
+{
+ return wcpu_map.wlcore_map[lcore_id].core_id;
+}
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_thread.c b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_thread.c
new file mode 100644
index 000000000..906502f90
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/eal_thread.c
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <io.h>
+
+#include <rte_atomic.h>
+#include <rte_debug.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_per_lcore.h>
+#include <rte_common.h>
+#include <eal_thread.h>
+
+
+RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY;
+
+/*
+ * Send a message to a slave lcore identified by slave_id to call a
+ * function f with argument arg. Once the execution is done, the
+ * remote lcore switch in FINISHED state.
+ */
+int
+rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned int slave_id)
+{
+ int n;
+ char c = 0;
+ int m2s = lcore_config[slave_id].pipe_master2slave[1];
+ int s2m = lcore_config[slave_id].pipe_slave2master[0];
+
+ if (lcore_config[slave_id].state != WAIT)
+ return -EBUSY;
+
+ lcore_config[slave_id].f = f;
+ lcore_config[slave_id].arg = arg;
+
+ /* send message */
+ n = 0;
+ while (n == 0 || (n < 0 && errno == EINTR))
+ n = _write(m2s, &c, 1);
+ if (n < 0)
+ rte_panic("cannot write on configuration pipe\n");
+
+ /* wait ack */
+ do {
+ n = _read(s2m, &c, 1);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0)
+ rte_panic("cannot read on configuration pipe\n");
+
+ return 0;
+}
+
+void
+eal_thread_init_master(unsigned int lcore_id)
+{
+ /* set the lcore ID in per-lcore memory area */
+ RTE_PER_LCORE(_lcore_id) = lcore_id;
+}
+
+static inline pthread_t
+eal_thread_self(void)
+{
+ return GetCurrentThreadId();
+}
+
+/* main loop of threads */
+void *
+eal_thread_loop(void *arg __rte_unused)
+{
+ char c;
+ int n, ret;
+ unsigned int lcore_id;
+ pthread_t thread_id;
+ int m2s, s2m;
+ char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+ thread_id = eal_thread_self();
+
+ /* retrieve our lcore_id from the configuration structure */
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ if (thread_id == lcore_config[lcore_id].thread_id)
+ break;
+ }
+ if (lcore_id == RTE_MAX_LCORE)
+ rte_panic("cannot retrieve lcore id\n");
+
+ m2s = lcore_config[lcore_id].pipe_master2slave[0];
+ s2m = lcore_config[lcore_id].pipe_slave2master[1];
+
+ /* set the lcore ID in per-lcore memory area */
+ RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+ RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%zx;cpuset=[%s])\n",
+ lcore_id, (uintptr_t)thread_id, cpuset);
+
+ /* read on our pipe to get commands */
+ while (1) {
+ void *fct_arg;
+
+ /* wait command */
+ do {
+ n = _read(m2s, &c, 1);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0)
+ rte_panic("cannot read on configuration pipe\n");
+
+ lcore_config[lcore_id].state = RUNNING;
+
+ /* send ack */
+ n = 0;
+ while (n == 0 || (n < 0 && errno == EINTR))
+ n = _write(s2m, &c, 1);
+ if (n < 0)
+ rte_panic("cannot write on configuration pipe\n");
+
+ if (lcore_config[lcore_id].f == NULL)
+ rte_panic("NULL function pointer\n");
+
+ /* call the function and store the return value */
+ fct_arg = lcore_config[lcore_id].arg;
+ ret = lcore_config[lcore_id].f(fct_arg);
+ lcore_config[lcore_id].ret = ret;
+ rte_wmb();
+
+ /* when a service core returns, it should go directly to WAIT
+ * state, because the application will not lcore_wait() for it.
+ */
+ if (lcore_config[lcore_id].core_role == ROLE_SERVICE)
+ lcore_config[lcore_id].state = WAIT;
+ else
+ lcore_config[lcore_id].state = FINISHED;
+ }
+}
+
+/* function to create threads */
+int
+eal_thread_create(pthread_t *thread)
+{
+ HANDLE th;
+
+ th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)eal_thread_loop,
+ NULL, 0, (LPDWORD)thread);
+ if (!th)
+ return -1;
+
+ SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
+ SetThreadPriority(th, THREAD_PRIORITY_TIME_CRITICAL);
+
+ return 0;
+}
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h
new file mode 100644
index 000000000..41b574312
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/fnmatch.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _FNMATCH_H_
+#define _FNMATCH_H_
+
+/**
+ * This file is required to support the common code in eal_common_log.c
+ * as Microsoft libc does not contain fnmatch.h. This may be removed in
+ * future releases.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FNM_NOMATCH 1
+
+/**
+ * This function is used for searhing a given string source
+ * with the given regular expression pattern.
+ *
+ * @param pattern
+ * regular expression notation decribing the pattern to match
+ *
+ * @param string
+ * source string to searcg for the pattern
+ *
+ * @param flag
+ * containing information about the pattern
+ *
+ * @return
+ * if the pattern is found then return 0 or else FNM_NOMATCH
+ */
+static inline int fnmatch(__rte_unused const char *pattern,
+ __rte_unused const char *string,
+ __rte_unused int flags)
+{
+ /* TODO */
+ /* This is a stub, not the expected result */
+ return FNM_NOMATCH;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FNMATCH_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/pthread.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/pthread.h
new file mode 100644
index 000000000..503329266
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/pthread.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _PTHREAD_H_
+#define _PTHREAD_H_
+
+/**
+ * This file is required to support the common code in eal_common_proc.c,
+ * eal_common_thread.c and common\include\rte_per_lcore.h as Microsoft libc
+ * does not contain pthread.h. This may be removed in future releases.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* defining pthread_t type on Windows since there is no in Microsoft libc*/
+typedef uintptr_t pthread_t;
+
+/* defining pthread_attr_t type on Windows since there is no in Microsoft libc*/
+typedef void *pthread_attr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PTHREAD_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/regex.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/regex.h
new file mode 100644
index 000000000..827f93841
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/regex.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _REGEX_H_
+#define _REGEX_H_
+
+/**
+ * This file is required to support the common code in eal_common_log.c
+ * as Microsoft libc does not contain regex.h. This may be removed in
+ * future releases.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define REG_NOMATCH 1
+#define REG_ESPACE 12
+
+#include <rte_common.h>
+
+/* defining regex_t for Windows */
+typedef void *regex_t;
+/* defining regmatch_t for Windows */
+typedef void *regmatch_t;
+
+/**
+ * The regcomp() function will compile the regular expression
+ * contained in the string pointed to by the pattern argument
+ * and place the results in the structure pointed to by preg.
+ * The cflags argument is the bitwise inclusive OR of zero or
+ * more of the flags
+ */
+static inline int regcomp(__rte_unused regex_t *preg,
+ __rte_unused const char *regex, __rte_unused int cflags)
+{
+ /* TODO */
+ /* This is a stub, not the expected result */
+ return REG_ESPACE;
+}
+
+/**
+ * The regexec() function compares the null-terminated string
+ * specified by string with the compiled regular expression
+ * preg initialised by a previous call to regcomp(). If it finds
+ * a match, regexec() returns 0; otherwise it returns non-zero
+ * indicating either no match or an error. The eflags argument
+ * is the bitwise inclusive OR of zero or more of the flags.
+ */
+static inline int regexec(__rte_unused const regex_t *preg,
+ __rte_unused const char *string, __rte_unused size_t nmatch,
+ __rte_unused regmatch_t pmatch[], __rte_unused int eflags)
+{
+ /* TODO */
+ /* This is a stub, not the expected result */
+ return REG_NOMATCH;
+}
+
+/**
+ * The regerror() function provides a mapping from error codes
+ * returned by regcomp() and regexec() to unspecified printable strings.
+ */
+static inline size_t regerror(__rte_unused int errcode,
+ __rte_unused const regex_t *preg, char *errbuf,
+ __rte_unused size_t errbuf_size)
+{
+ /* TODO */
+ /* This is a stub, not the expected result */
+ if (errbuf) {
+ *errbuf = '\0';
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * The regfree() function frees any memory allocated by regcomp()
+ * associated with preg.
+ */
+static inline void regfree(__rte_unused regex_t *preg)
+{
+ /* TODO */
+ /* This is a stub, not the expected result */
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _REGEX_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/rte_os.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/rte_os.h
new file mode 100644
index 000000000..fdeae0c8f
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/rte_os.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ */
+
+#ifndef _RTE_OS_H_
+#define _RTE_OS_H_
+
+/**
+ * This is header should contain any function/macro definition
+ * which are not supported natively or named differently in the
+ * Windows OS. Functions will be added in future releases.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Windows.h>
+#include <BaseTsd.h>
+#include <pthread.h>
+
+#define strerror_r(a, b, c) strerror_s(b, c, a)
+
+/* strdup is deprecated in Microsoft libc and _strdup is preferred */
+#define strdup(str) _strdup(str)
+
+typedef SSIZE_T ssize_t;
+
+#define strtok_r(str, delim, saveptr) strtok_s(str, delim, saveptr)
+
+/**
+ * Create a thread.
+ * This function is private to EAL.
+ *
+ * @param thread
+ * The location to store the thread id if successful.
+ * @return
+ * 0 for success, -1 if the thread is not created.
+ */
+int eal_thread_create(pthread_t *thread);
+
+/**
+ * Create a map of processors and cores on the system.
+ * This function is private to EAL.
+ */
+void eal_create_cpu_map(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_OS_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sched.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sched.h
new file mode 100644
index 000000000..257060594
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sched.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _SCHED_H_
+#define _SCHED_H_
+
+/**
+ * This file is added to support the common code in eal_common_thread.c
+ * as Microsoft libc does not contain sched.h. This may be removed
+ * in future releases.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CPU_SET_SIZE
+#define CPU_SET_SIZE RTE_MAX_LCORE
+#endif
+
+#define _BITS_PER_SET (sizeof(long long) * 8)
+#define _BIT_SET_MASK (_BITS_PER_SET - 1)
+
+#define _NUM_SETS(b) (((b) + _BIT_SET_MASK) / _BITS_PER_SET)
+#define _WHICH_SET(b) ((b) / _BITS_PER_SET)
+#define _WHICH_BIT(b) ((b) & (_BITS_PER_SET - 1))
+
+typedef struct _rte_cpuset_s {
+ long long _bits[_NUM_SETS(CPU_SET_SIZE)];
+} rte_cpuset_t;
+
+#define CPU_SET(b, s) ((s)->_bits[_WHICH_SET(b)] |= (1LL << _WHICH_BIT(b)))
+
+#define CPU_ZERO(s) \
+ do { \
+ unsigned int _i; \
+ \
+ for (_i = 0; _i < _NUM_SETS(CPU_SET_SIZE); _i++) \
+ (s)->_bits[_i] = 0LL; \
+ } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SCHED_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sys/queue.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sys/queue.h
new file mode 100644
index 000000000..5ee4916ad
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/sys/queue.h
@@ -0,0 +1,320 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines tail queues.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * Below is a summary of implemented functions where:
+ * + means the macro is available
+ * - means the macro is not available
+ * s means the macro is available but is slow (runs in O(n) time)
+ *
+ * TAILQ
+ * _HEAD +
+ * _CLASS_HEAD +
+ * _HEAD_INITIALIZER +
+ * _ENTRY +
+ * _CLASS_ENTRY +
+ * _INIT +
+ * _EMPTY +
+ * _FIRST +
+ * _NEXT +
+ * _PREV +
+ * _LAST +
+ * _LAST_FAST +
+ * _FOREACH +
+ * _FOREACH_FROM +
+ * _FOREACH_SAFE +
+ * _FOREACH_FROM_SAFE +
+ * _FOREACH_REVERSE +
+ * _FOREACH_REVERSE_FROM +
+ * _FOREACH_REVERSE_SAFE +
+ * _FOREACH_REVERSE_FROM_SAFE +
+ * _INSERT_HEAD +
+ * _INSERT_BEFORE +
+ * _INSERT_AFTER +
+ * _INSERT_TAIL +
+ * _CONCAT +
+ * _REMOVE_AFTER -
+ * _REMOVE_HEAD -
+ * _REMOVE +
+ * _SWAP +
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define QMD_TRACE_ELEM(elem)
+#define QMD_TRACE_HEAD(head)
+#define TRACEBUF
+#define TRACEBUF_INITIALIZER
+
+#define TRASHIT(x)
+#define QMD_IS_TRASHED(x) 0
+
+#define QMD_SAVELINK(name, link)
+
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define QUEUE_TYPEOF(type) type
+#else
+#define QUEUE_TYPEOF(type) struct type
+#endif
+
+/*
+ * Tail queue declarations.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *tqh_first; /* first element */ \
+ class type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+#define TAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *tqe_next; /* next element */ \
+ class type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
+/*
+ * Tail queue functions.
+ */
+#define QMD_TAILQ_CHECK_HEAD(head, field)
+#define QMD_TAILQ_CHECK_TAIL(head, headname)
+#define QMD_TAILQ_CHECK_NEXT(elm, field)
+#define QMD_TAILQ_CHECK_PREV(elm, field)
+
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ QMD_TRACE_HEAD(head1); \
+ QMD_TRACE_HEAD(head2); \
+ } \
+} while (0)
+
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#define TAILQ_FOREACH_FROM(var, head, field) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var); \
+ (var) = TAILQ_NEXT((var), field))
+
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
+ for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
+ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
+ (var) = (tvar))
+
+#define TAILQ_INIT(head) do { \
+ TAILQ_FIRST((head)) = NULL; \
+ (head)->tqh_last = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ QMD_TAILQ_CHECK_NEXT(listelm, field); \
+ TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field); \
+ if (TAILQ_NEXT((listelm), field) != NULL) \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else { \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ } \
+ TAILQ_NEXT((listelm), field) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ QMD_TAILQ_CHECK_PREV(listelm, field); \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ TAILQ_NEXT((elm), field) = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ QMD_TAILQ_CHECK_HEAD(head, field); \
+ TAILQ_NEXT((elm), field) = TAILQ_FIRST((head)); \
+ if (TAILQ_FIRST((head)) != NULL) \
+ TAILQ_FIRST((head))->field.tqe_prev = \
+ &TAILQ_NEXT((elm), field); \
+ else \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ TAILQ_FIRST((head)) = (elm); \
+ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ QMD_TAILQ_CHECK_TAIL(head, field); \
+ TAILQ_NEXT((elm), field) = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ QMD_TRACE_HEAD(head); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+/*
+ * The FAST function is fast in that it causes no data access other
+ * then the access to the head. The standard LAST function above
+ * will cause a data access of both the element you want and
+ * the previous element. FAST is very useful for instances when
+ * you may want to prefetch the last data element.
+ */
+#define TAILQ_LAST_FAST(head, type, field) \
+ (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, \
+ QUEUE_TYPEOF(type), field.tqe_next))
+
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
+ QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
+ QMD_TAILQ_CHECK_NEXT(elm, field); \
+ QMD_TAILQ_CHECK_PREV(elm, field); \
+ if ((TAILQ_NEXT((elm), field)) != NULL) \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else { \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ QMD_TRACE_HEAD(head); \
+ } \
+ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
+ TRASHIT(*oldnext); \
+ TRASHIT(*oldprev); \
+ QMD_TRACE_ELEM(&(elm)->field); \
+} while (0)
+
+#define TAILQ_SWAP(head1, head2, type, field) do { \
+ QUEUE_TYPEOF(type) * swap_first = (head1)->tqh_first; \
+ QUEUE_TYPEOF(type) * *swap_last = (head1)->tqh_last; \
+ (head1)->tqh_first = (head2)->tqh_first; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ (head2)->tqh_first = swap_first; \
+ (head2)->tqh_last = swap_last; \
+ swap_first = (head1)->tqh_first; \
+ if (swap_first != NULL) \
+ swap_first->field.tqe_prev = &(head1)->tqh_first; \
+ else \
+ (head1)->tqh_last = &(head1)->tqh_first; \
+ swap_first = (head2)->tqh_first; \
+ if (swap_first != NULL) \
+ swap_first->field.tqe_prev = &(head2)->tqh_first; \
+ else \
+ (head2)->tqh_last = &(head2)->tqh_first; \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_QUEUE_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/include/unistd.h b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/unistd.h
new file mode 100644
index 000000000..757b7f3c5
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/include/unistd.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+/**
+ * This file is added to support common code in eal_common_lcore.c
+ * as Microsoft libc does not contain unistd.h. This may be removed
+ * in future releases.
+ */
+#endif /* _UNISTD_H_ */
diff --git a/src/seastar/dpdk/lib/librte_eal/windows/eal/meson.build b/src/seastar/dpdk/lib/librte_eal/windows/eal/meson.build
new file mode 100644
index 000000000..af4f70f00
--- /dev/null
+++ b/src/seastar/dpdk/lib/librte_eal/windows/eal/meson.build
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+eal_inc += include_directories('include')
+
+env_objs = []
+env_headers = files(
+ 'include/rte_os.h',
+)
+common_sources = files(
+ '../../common/eal_common_errno.c',
+ '../../common/eal_common_launch.c',
+ '../../common/eal_common_lcore.c',
+ '../../common/eal_common_log.c'
+)
+env_sources = files('eal.c',
+ 'eal_debug.c',
+ 'eal_lcore.c',
+ 'eal_thread.c',
+)