add FreeBSD support
authorBruce Richardson <bruce.richardson@intel.com>
Mon, 10 Feb 2014 11:49:10 +0000 (11:49 +0000)
committerDavid Marchand <david.marchand@6wind.com>
Tue, 25 Feb 2014 20:29:18 +0000 (21:29 +0100)
Changes to allow compilation and use on FreeBSD. Includes:
* contigmem and nic_uio driver for FreeBSD
* new EAL instance
* new "bsdapp" compilation target
* various compilation fixes due to differences between linux and freebsd

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
55 files changed:
GNUmakefile [new file with mode: 0644]
Makefile
app/test-pmd/cmdline.c
app/test/commands.c
app/test/process.h
app/test/test_cmdline_ipaddr.c
app/test/test_eal_flags.c
app/test/test_eal_fs.c
app/test/test_errno.c
app/test/test_mp_secondary.c
config/defconfig_x86_64-default-bsdapp-gcc [new file with mode: 0644]
examples/cmdline/commands.c
lib/librte_cmdline/Makefile
lib/librte_cmdline/cmdline_parse_ipaddr.c
lib/librte_cmdline/cmdline_parse_portlist.c
lib/librte_eal/Makefile
lib/librte_eal/bsdapp/Makefile [new file with mode: 0644]
lib/librte_eal/bsdapp/contigmem/BSDmakefile [new file with mode: 0644]
lib/librte_eal/bsdapp/contigmem/Makefile [new file with mode: 0644]
lib/librte_eal/bsdapp/contigmem/contigmem.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/Makefile [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_alarm.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_debug.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_hugepage_info.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_interrupts.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_lcore.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_log.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_memory.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_pci.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_thread.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/eal_timer.c [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/eal_filesystem.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/eal_hugepages.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/eal_internal_cfg.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/eal_thread.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/exec-env/rte_kni_common.h [new file with mode: 0755]
lib/librte_eal/bsdapp/eal/include/exec-env/rte_lcore.h [new file with mode: 0644]
lib/librte_eal/bsdapp/eal/include/exec-env/rte_per_lcore.h [new file with mode: 0644]
lib/librte_eal/bsdapp/nic_uio/BSDmakefile [new file with mode: 0644]
lib/librte_eal/bsdapp/nic_uio/Makefile [new file with mode: 0644]
lib/librte_eal/bsdapp/nic_uio/nic_uio.c [new file with mode: 0644]
lib/librte_eal/common/eal_common_errno.c
lib/librte_eal/common/eal_common_log.c
lib/librte_eal/common/include/rte_memory.h
lib/librte_eal/linuxapp/eal/eal_log.c
lib/librte_pmd_pcap/rte_eth_pcap_arg_parser.c
lib/librte_pmd_virtio/virtio_pci.h
mk/arch/x86_64/rte.vars.mk
mk/exec-env/bsdapp/rte.app.mk [new file with mode: 0644]
mk/exec-env/bsdapp/rte.vars.mk [new file with mode: 0644]
mk/rte.bsdmodule.mk [new file with mode: 0644]
mk/rte.sdkbuild.mk

diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644 (file)
index 0000000..7afb9ee
--- /dev/null
@@ -0,0 +1,45 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+#
+# Head Makefile for compiling rte SDK
+#
+
+RTE_SDK := $(CURDIR)
+export RTE_SDK
+
+#
+# directory list
+#
+
+ROOTDIRS-y := scripts lib app
+
+include $(RTE_SDK)/mk/rte.sdkroot.mk
index 7afb9ee..d789491 100644 (file)
--- a/Makefile
+++ b/Makefile
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#
-# Head Makefile for compiling rte SDK
-#
+.error Error please compile using GNU Make (gmake)
 
-RTE_SDK := $(CURDIR)
-export RTE_SDK
-
-#
-# directory list
-#
-
-ROOTDIRS-y := scripts lib app
-
-include $(RTE_SDK)/mk/rte.sdkroot.mk
index 062a233..4bf0720 100644 (file)
 #include <unistd.h>
 #include <inttypes.h>
 #ifndef __linux__
+#ifndef __FreeBSD__
 #include <net/socket.h>
+#else
+#include <sys/socket.h>
+#endif
 #endif
 #include <netinet/in.h>
 
index 4770817..118f70d 100644 (file)
 #include <netinet/in.h>
 #include <termios.h>
 #ifndef __linux__
+#ifndef __FreeBSD__
 #include <net/socket.h>
 #endif
+#endif
 #include <inttypes.h>
 #include <errno.h>
 #include <sys/queue.h>
index 8894360..f896b04 100644 (file)
 
 #ifndef RTE_EXEC_ENV_BAREMETAL
 
+#ifdef RTE_EXEC_ENV_BSDAPP
+#define self "curproc"
+#define exe "file"
+#else
+#define self "self"
+#define exe "exe"
+#endif
+
 /*
  * launches a second copy of the test process using the given argv parameters,
  * which should include argv[0] as the process name. To identify in the
@@ -61,7 +69,7 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
                /* close all open file descriptors, check /proc/self/fd to only
                 * call close on open fds. Exclude fds 0, 1 and 2*/
                for (fd = getdtablesize(); fd > 2; fd-- ) {
-                       rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
+                       rte_snprintf(path, sizeof(path), "/proc/" exe "/fd/%d", fd);
                        if (access(path, F_OK) == 0)
                                close(fd);
                }
@@ -73,7 +81,7 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
                /* set the environment variable */
                if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0)
                        rte_panic("Cannot export environment variable\n");
-               if (execv("/proc/self/exe", argv_cpy) < 0)
+               if (execv("/proc/" self "/" exe, argv_cpy) < 0)
                        rte_panic("Cannot exec\n");
        }
        /* parent process does a wait */
index 4c9eb55..c809411 100644 (file)
 #include <netinet/in.h>
 
 #ifndef __linux__
+#ifndef __FreeBSD__
 #include <net/socket.h>
+#else
+#include <sys/socket.h>
+#endif
 #endif
 
 #include <rte_string_fns.h>
                (((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
 
 /* create IPv6 address, swapping bytes where needed */
+#ifndef s6_addr16
+# define s6_addr16      __u6_addr.__u6_addr16
+#endif
 #define IP6(a,b,c,d,e,f,g,h) .ipv6 = \
                {.s6_addr16 = \
                {U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\
                 U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}}
 
 /** these are defined in netinet/in.h but not present in linux headers */
-#ifdef __linux__
+#ifndef NIPQUAD
+
 #define NIPQUAD_FMT "%u.%u.%u.%u"
 #define NIPQUAD(addr)                          \
        (unsigned)((unsigned char *)&addr)[0],  \
@@ -88,6 +96,7 @@
        (unsigned)((addr).s6_addr[13]),                 \
        (unsigned)((addr).s6_addr[14]),                 \
        (unsigned)((addr).s6_addr[15])
+
 #endif
 
 
index 5517f86..2d09385 100644 (file)
@@ -47,6 +47,7 @@
 #include <dirent.h>
 #include <sys/wait.h>
 #include <sys/file.h>
+#include <limits.h>
 
 #include <rte_debug.h>
 #include <rte_string_fns.h>
@@ -217,6 +218,7 @@ end:
        return result;
 }
 
+#ifdef RTE_EXEC_ENV_LINUXAPP
 /*
  * count the number of "node*" files in /sys/devices/system/node/
  */
@@ -246,6 +248,7 @@ get_number_of_sockets(void)
        closedir(dir);
        return result;
 }
+#endif
 
 static char*
 get_current_prefix(char * prefix, int size)
@@ -293,12 +296,17 @@ static int
 test_whitelist_flag(void)
 {
        unsigned i;
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#endif
 
        const char *wlinval[][11] = {
                {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
@@ -381,12 +389,17 @@ test_whitelist_flag(void)
 static int
 test_invalid_b_flag(void)
 {
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#endif
 
        const char *blinval[][9] = {
                {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
@@ -422,12 +435,17 @@ test_invalid_b_flag(void)
 static int
 test_invalid_r_flag(void)
 {
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#endif
 
        const char *rinval[][9] = {
                        {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
@@ -461,12 +479,17 @@ test_invalid_r_flag(void)
 static int
 test_missing_c_flag(void)
 {
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#endif
 
        /* -c flag but no coremask value */
        const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
@@ -499,12 +522,17 @@ test_missing_c_flag(void)
 static int
 test_missing_n_flag(void)
 {
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#endif
 
        /* -n flag but no value */
        const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
@@ -538,6 +566,10 @@ static int
 test_no_hpet_flag(void)
 {
        char prefix[PATH_MAX], tmp[PATH_MAX];
+
+#ifdef RTE_EXEC_ENV_BSDAPP
+       return 0;
+#endif
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
@@ -567,26 +599,25 @@ test_no_hpet_flag(void)
 static int
 test_no_huge_flag(void)
 {
-       char prefix[PATH_MAX], tmp[PATH_MAX];
-       if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
-               printf("Error - unable to get current prefix!\n");
-               return -1;
-       }
-       rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point, and we also need to
+        * run another primary process here */
+       const char * prefix = no_shconf;
+#else
+       const char * prefix = "--file-prefix=nohuge";
+#endif
 
        /* With --no-huge */
-       const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
-                       "--file-prefix=nohuge"};
+       const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"};
        /* With --no-huge and -m */
-       const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2",
-                       "--file-prefix=nohuge"};
+       const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2"};
+
        /* With --no-huge and --socket-mem */
        const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
-                       "--socket-mem=2", "--file-prefix=nohuge"};
+                       "--socket-mem=2"};
        /* With --no-huge, -m and --socket-mem */
        const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
-                       "-m", "2", "--socket-mem=2", "--file-prefix=nohuge"};
-
+                       "-m", "2", "--socket-mem=2"};
        if (launch_proc(argv1) != 0) {
                printf("Error - process did not run ok with --no-huge flag\n");
                return -1;
@@ -595,6 +626,11 @@ test_no_huge_flag(void)
                printf("Error - process run ok with --no-huge and -m flags\n");
                return -1;
        }
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target does not support NUMA, hence no --socket-mem tests */
+       return 0;
+#endif
+
        if (launch_proc(argv3) == 0) {
                printf("Error - process run ok with --no-huge and --socket-mem "
                                "flags\n");
@@ -611,12 +647,17 @@ test_no_huge_flag(void)
 static int
 test_misc_flags(void)
 {
-       FILE * hugedir_handle = NULL;
-       char line[PATH_MAX] = {0};
        char hugepath[PATH_MAX] = {0};
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+       const char * nosh_prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
+       const char * nosh_prefix = "--file-prefix=noshconf";
+       FILE * hugedir_handle = NULL;
+       char line[PATH_MAX] = {0};
        unsigned i, isempty = 1;
-
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
@@ -654,6 +695,7 @@ test_misc_flags(void)
                printf("No mounted hugepage dir found!\n");
                return -1;
        }
+#endif
 
 
        /* check that some general flags don't prevent things from working.
@@ -676,7 +718,11 @@ test_misc_flags(void)
        const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
        /* With no-sh-conf */
        const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
-                       "--no-shconf", "--file-prefix=noshconf" };
+                       no_shconf, nosh_prefix };
+
+#ifdef RTE_EXEC_ENV_BSDAPP
+       return 0;
+#endif
        /* With --huge-dir */
        const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
                        "--file-prefix=hugedir", "--huge-dir", hugepath};
@@ -719,6 +765,9 @@ test_misc_flags(void)
                printf("Error - process did not run ok with --no-shconf flag\n");
                return -1;
        }
+#ifdef RTE_EXEC_ENV_BSDAPP
+       return 0;
+#endif
        if (launch_proc(argv7) != 0) {
                printf("Error - process did not run ok with --huge-dir flag\n");
                return -1;
@@ -752,6 +801,10 @@ test_file_prefix(void)
         * 7. check that only memtest2 hugefiles are present in the hugedir
         */
 
+#ifdef RTE_EXEC_ENV_BSDAPP
+       return 0;
+#endif
+
        /* this should fail unless the test itself is run with "memtest" prefix */
        const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", "2",
                        "--file-prefix=" memtest };
@@ -852,13 +905,17 @@ test_file_prefix(void)
 static int
 test_memory_flags(void)
 {
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD target doesn't support prefixes at this point */
+       const char * prefix = "";
+#else
        char prefix[PATH_MAX], tmp[PATH_MAX];
        if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
                printf("Error - unable to get current prefix!\n");
                return -1;
        }
        rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
-
+#endif
        /* valid -m flag */
        const char *argv0[] = {prgname, "-c", "10", "-n", "2",
                        "--file-prefix=" memtest, "-m", "2"};
@@ -899,7 +956,12 @@ test_memory_flags(void)
         * extra 2 megs on socket that doesn't exist on current system */
        char invalid_socket_mem[SOCKET_MEM_STRLEN];
        char buf[SOCKET_MEM_STRLEN];    /* to avoid copying string onto itself */
+
+#ifdef RTE_EXEC_ENV_BSDAPP
+       int i, num_sockets = 1;
+#else
        int i, num_sockets = get_number_of_sockets();
+#endif
 
        if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) {
                printf("Error - cannot get number of sockets!\n");
@@ -944,10 +1006,15 @@ test_memory_flags(void)
                        "--file-prefix=" memtest, valid_socket_mem};
 
        if (launch_proc(argv0) != 0) {
-               printf("Error - process failed with valid -m flag!\n");
+               printf("Error - secondary process failed with valid -m flag !\n");
                return -1;
        }
 
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* no other tests are applicable to BSD */
+       return 0;
+#endif
+
        if (launch_proc(argv1) != 0) {
                printf("Error - secondary process failed with valid -m flag !\n");
                return -1;
index 438d4dc..93d8a7f 100644 (file)
@@ -53,6 +53,11 @@ test_parse_sysfs_value(void)
        unsigned valid_number;
        unsigned long retval = 0;
 
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD doesn't have /proc/pid/fd */
+       return 0;
+#endif
+
        printf("Testing function eal_parse_sysfs_value()\n");
 
        /* get a temporary filename to use for all tests - create temp file handle and then
index 0af4f78..24065e5 100644 (file)
@@ -49,7 +49,12 @@ test_errno(void)
 {
        const char *rte_retval;
        const char *libc_retval;
+#ifdef RTE_EXEC_ENV_BSDAPP
+       /* BSD has a colon in the string, unlike linux */
+       const char unknown_code_result[] = "Unknown error: %d";
+#else
        const char unknown_code_result[] = "Unknown error %d";
+#endif
        char expected_libc_retval[sizeof(unknown_code_result)+3];
 
        /* use a small selection of standard errors for testing */
index 64efb39..aceb567 100644 (file)
@@ -53,6 +53,7 @@
 #include <sys/wait.h>
 #include <libgen.h>
 #include <dirent.h>
+#include <limits.h>
 
 #include <rte_common.h>
 #include <rte_memory.h>
diff --git a/config/defconfig_x86_64-default-bsdapp-gcc b/config/defconfig_x86_64-default-bsdapp-gcc
new file mode 100644 (file)
index 0000000..e415825
--- /dev/null
@@ -0,0 +1,297 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+#
+
+#
+# define executive environment
+#
+# CONFIG_RTE_EXEC_ENV can be linuxapp, baremetal, bsdapp
+#
+CONFIG_RTE_EXEC_ENV="bsdapp"
+CONFIG_RTE_EXEC_ENV_BSDAPP=y
+
+#
+# machine can define specific variables or action for a specific board
+# RTE_MACHINE can be:
+# default  nothing specific
+# native   current machine
+# atm      Intel® Atomâ„¢ microarchitecture
+# nhm      Intel® microarchitecture code name Nehalem
+# wsm      Intel® microarchitecture code name Westmere
+# snb      Intel® microarchitecture code name Sandy Bridge
+# ivb      Intel® microarchitecture code name Ivy Bridge
+#
+# Note: if your compiler does not support the relevant -march options,
+# it will be compiled with whatever latest processor the compiler supports!
+#
+CONFIG_RTE_MACHINE="native"
+
+#
+# define the architecture we compile for.
+# CONFIG_RTE_ARCH can be i686, x86_64, x86_64_32
+#
+CONFIG_RTE_ARCH="x86_64"
+CONFIG_RTE_ARCH_X86_64=y
+
+#
+# The compiler we use.
+# Can be gcc or icc.
+#
+CONFIG_RTE_TOOLCHAIN="gcc"
+CONFIG_RTE_TOOLCHAIN_GCC=y
+
+#
+# Use intrinsics or assembly code for key routines
+#
+CONFIG_RTE_FORCE_INTRINSICS=n
+
+#
+# Compile to share library
+#
+CONFIG_RTE_LIBNAME=intel_dpdk
+CONFIG_RTE_BUILD_SHARED_LIB=n
+
+#
+# Combine to one single library
+#
+CONFIG_RTE_BUILD_COMBINE_LIBS=n
+
+#
+# Compile Environment Abstraction Layer
+#
+CONFIG_RTE_LIBRTE_EAL=y
+CONFIG_RTE_MAX_LCORE=64
+CONFIG_RTE_MAX_NUMA_NODES=8
+CONFIG_RTE_MAX_MEMSEG=256
+CONFIG_RTE_MAX_MEMZONE=2560
+CONFIG_RTE_MAX_TAILQ=32
+CONFIG_RTE_LOG_LEVEL=8
+CONFIG_RTE_LOG_HISTORY=256
+CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
+
+#
+# FreeBSD contiguous memory driver settings
+#
+CONFIG_RTE_CONTIGMEM_MAX_NUM_BUFS=64
+CONFIG_RTE_CONTIGMEM_DEFAULT_NUM_BUFS=2
+CONFIG_RTE_CONTIGMEM_DEFAULT_BUF_SIZE=1024*1024*1024
+
+#
+# Compile Environment Abstraction Layer for BSD
+#
+CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
+
+#
+# Compile Environment Abstraction Layer for linux
+#
+CONFIG_RTE_LIBRTE_EAL_LINUXAPP=n
+
+#
+# Compile Environment Abstraction Layer for Bare metal
+#
+CONFIG_RTE_LIBRTE_EAL_BAREMETAL=n
+
+#
+# Compile Environment Abstraction Layer to support Vmware TSC map
+# 
+CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
+
+#
+# Compile generic ethernet library
+#
+CONFIG_RTE_LIBRTE_ETHER=y
+CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
+CONFIG_RTE_MAX_ETHPORTS=32
+CONFIG_RTE_LIBRTE_IEEE1588=n
+CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
+
+#
+# Compile burst-oriented IGB & EM PMD drivers
+#
+CONFIG_RTE_LIBRTE_EM_PMD=y
+CONFIG_RTE_LIBRTE_IGB_PMD=y
+CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
+
+#
+# Compile burst-oriented IXGBE PMD driver
+#
+CONFIG_RTE_LIBRTE_IXGBE_PMD=y
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
+CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
+CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y
+CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=n
+
+#
+# Compile burst-oriented VIRTIO PMD driver
+#
+CONFIG_RTE_LIBRTE_VIRTIO_PMD=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
+
+#
+# Compile example software rings based PMD
+#
+CONFIG_RTE_LIBRTE_PMD_RING=y
+CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
+CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
+
+#
+# Compile software PMD backed by PCAP files
+#
+CONFIG_RTE_LIBRTE_PMD_PCAP=y
+
+#
+# Do prefetch of packet data within PMD driver receive function
+#
+CONFIG_RTE_PMD_PACKET_PREFETCH=y
+
+#
+# Compile librte_ring
+#
+CONFIG_RTE_LIBRTE_RING=y
+CONFIG_RTE_LIBRTE_RING_DEBUG=n
+CONFIG_RTE_RING_SPLIT_PROD_CONS=n
+
+#
+# Compile librte_mempool
+#
+CONFIG_RTE_LIBRTE_MEMPOOL=y
+CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
+CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
+
+#
+# Compile librte_mbuf
+#
+CONFIG_RTE_LIBRTE_MBUF=y
+CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
+CONFIG_RTE_MBUF_SCATTER_GATHER=y
+CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
+CONFIG_RTE_PKTMBUF_HEADROOM=128
+
+#
+# Compile librte_timer
+#
+CONFIG_RTE_LIBRTE_TIMER=y
+CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
+
+#
+# Compile librte_malloc
+#
+CONFIG_RTE_LIBRTE_MALLOC=y
+CONFIG_RTE_LIBRTE_MALLOC_DEBUG=n
+CONFIG_RTE_MALLOC_MEMZONE_SIZE=11M
+
+#
+# Compile librte_cmdline
+#
+CONFIG_RTE_LIBRTE_CMDLINE=y
+CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
+
+#
+# Compile librte_hash
+#
+CONFIG_RTE_LIBRTE_HASH=y
+CONFIG_RTE_LIBRTE_HASH_DEBUG=n
+
+#
+# Compile librte_lpm
+#
+CONFIG_RTE_LIBRTE_LPM=y
+CONFIG_RTE_LIBRTE_LPM_DEBUG=n
+
+#
+# Compile librte_power
+#
+CONFIG_RTE_LIBRTE_POWER=n
+CONFIG_RTE_LIBRTE_POWER_DEBUG=n
+CONFIG_RTE_MAX_LCORE_FREQS=64
+
+#
+# Compile librte_net
+#
+CONFIG_RTE_LIBRTE_NET=y
+
+#
+# Compile librte_meter
+#
+CONFIG_RTE_LIBRTE_METER=y
+
+#
+# Compile librte_sched
+#
+CONFIG_RTE_LIBRTE_SCHED=y
+CONFIG_RTE_SCHED_RED=n
+CONFIG_RTE_SCHED_COLLECT_STATS=n
+CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
+CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
+
+#
+# Compile the test application
+# Compile librte_kni
+#
+CONFIG_RTE_LIBRTE_KNI=n
+CONFIG_RTE_LIBRTE_KNI_DEBUG=n
+CONFIG_RTE_KNI_KO_DEBUG=n
+CONFIG_RTE_KNI_VHOST=n
+CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
+CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
+CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
+CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
+
+#
+# Enable warning directives
+#
+CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
+
+#
+# Compile the test application
+#
+CONFIG_RTE_APP_TEST=y
+
+#
+# Compile the PMD test application
+#
+CONFIG_RTE_TEST_PMD=y
+CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
+CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
index 60d1909..afce715 100644 (file)
 #include <netinet/in.h>
 #include <termios.h>
 #ifndef __linux__
-#include <net/socket.h>
+       #ifdef __FreeBSD__
+               #include <sys/socket.h>
+       #else
+               #include <net/socket.h>
+       #endif
 #endif
 
 #include <cmdline_rdline.h>
index d763157..3c840e1 100644 (file)
@@ -49,7 +49,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
 
-CFLAGS_cmdline.o := -D_GNU_SOURCE
+CFLAGS += -D_GNU_SOURCE
 
 # install includes
 INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
index 68f4625..2861fc7 100644 (file)
 #include <errno.h>
 #include <netinet/in.h>
 #ifndef __linux__
+#ifndef __FreeBSD__
 #include <net/socket.h>
+#else
+#include <sys/socket.h>
+#endif
 #endif
 
 #include <rte_string_fns.h>
index f28b43b..e997f30 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <stdarg.h>
-#include <netinet/in.h>
-#ifndef __linux__
-#include <net/socket.h>
-#endif
 
 #include <rte_string_fns.h>
 #include "cmdline_parse.h"
index 30cbd9b..586fddc 100644 (file)
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += common
 DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += linuxapp
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += common
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += bsdapp
 DIRS-$(CONFIG_RTE_LIBRTE_EAL_BAREMETAL) += baremetal
 DIRS-$(CONFIG_RTE_LIBRTE_EAL_BAREMETAL) += common
 
diff --git a/lib/librte_eal/bsdapp/Makefile b/lib/librte_eal/bsdapp/Makefile
new file mode 100644 (file)
index 0000000..22fc4a3
--- /dev/null
@@ -0,0 +1,38 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += contigmem
+DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += nic_uio
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/librte_eal/bsdapp/contigmem/BSDmakefile b/lib/librte_eal/bsdapp/contigmem/BSDmakefile
new file mode 100644 (file)
index 0000000..9af486d
--- /dev/null
@@ -0,0 +1,36 @@
+#   BSD LICENSE 
+#  
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 
+#   All rights reserved. 
+#  
+#   Redistribution and use in source and binary forms, with or without 
+#   modification, are permitted provided that the following conditions 
+#   are met: 
+#  
+#     * Redistributions of source code must retain the above copyright 
+#       notice, this list of conditions and the following disclaimer. 
+#     * 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. 
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT 
+#   OWNER 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. 
+#
+
+KMOD=  contigmem
+SRCS=  contigmem.c device_if.h bus_if.h
+
+.include <bsd.kmod.mk>
diff --git a/lib/librte_eal/bsdapp/contigmem/Makefile b/lib/librte_eal/bsdapp/contigmem/Makefile
new file mode 100644 (file)
index 0000000..1818501
--- /dev/null
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# module name and path
+#
+MODULE = contigmem
+
+#
+# CFLAGS
+#
+MODULE_CFLAGS += -I$(SRCDIR) 
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
+MODULE_CFLAGS += -Winline -Wall -Werror
+MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-y := contigmem.c
+
+include $(RTE_SDK)/mk/rte.bsdmodule.mk
diff --git a/lib/librte_eal/bsdapp/contigmem/contigmem.c b/lib/librte_eal/bsdapp/contigmem/contigmem.c
new file mode 100644 (file)
index 0000000..dfe3a90
--- /dev/null
@@ -0,0 +1,233 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+static int              contigmem_load(void);
+static int              contigmem_unload(void);
+static int              contigmem_physaddr(SYSCTL_HANDLER_ARGS);
+
+static d_mmap_t         contigmem_mmap;
+static d_mmap_single_t  contigmem_mmap_single;
+static d_open_t         contigmem_open;
+
+static int              contigmem_num_buffers = RTE_CONTIGMEM_DEFAULT_NUM_BUFS;
+static int              contigmem_buffer_size = RTE_CONTIGMEM_DEFAULT_BUF_SIZE;
+
+static eventhandler_tag contigmem_eh_tag;
+static void            *contigmem_buffers[RTE_CONTIGMEM_MAX_NUM_BUFS];
+static struct cdev     *contigmem_cdev = NULL;
+
+TUNABLE_INT("hw.contigmem.num_buffers", &contigmem_num_buffers);
+TUNABLE_INT("hw.contigmem.buffer_size", &contigmem_buffer_size);
+
+static SYSCTL_NODE(_hw, OID_AUTO, contigmem, CTLFLAG_RD, 0, "contigmem");
+
+SYSCTL_INT(_hw_contigmem, OID_AUTO, num_buffers, CTLFLAG_RD,
+       &contigmem_num_buffers, 0, "Number of contigmem buffers allocated");
+SYSCTL_INT(_hw_contigmem, OID_AUTO, buffer_size, CTLFLAG_RD,
+       &contigmem_buffer_size, 0, "Size of each contiguous buffer");
+
+static SYSCTL_NODE(_hw_contigmem, OID_AUTO, physaddr, CTLFLAG_RD, 0,
+       "physaddr");
+
+MALLOC_DEFINE(M_CONTIGMEM, "contigmem", "contigmem(4) allocations");
+
+static int contigmem_modevent(module_t mod, int type, void *arg)
+{
+       int error = 0;
+
+       switch (type) {
+       case MOD_LOAD:
+               error = contigmem_load();
+               break;
+       case MOD_UNLOAD:
+               error = contigmem_unload();
+               break;
+       default:
+               break;
+       }
+
+       return (error);
+}
+
+moduledata_t contigmem_mod = {
+       "contigmem",
+       (modeventhand_t)contigmem_modevent,
+       0
+};
+
+DECLARE_MODULE(contigmem, contigmem_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
+MODULE_VERSION(contigmem, 1);
+
+static struct cdevsw contigmem_ops = {
+       .d_name         = "contigmem",
+       .d_version      = D_VERSION,
+       .d_mmap         = contigmem_mmap,
+       .d_mmap_single  = contigmem_mmap_single,
+       .d_open         = contigmem_open,
+};
+
+static int
+contigmem_load()
+{
+       char index_string[8], description[32];
+       int  i;
+
+       if (contigmem_num_buffers > RTE_CONTIGMEM_MAX_NUM_BUFS) {
+               printf("%d buffers requested is greater than %d allowed\n",
+                               contigmem_num_buffers, RTE_CONTIGMEM_MAX_NUM_BUFS);
+               return (EINVAL);
+       }
+
+       if (contigmem_buffer_size < PAGE_SIZE ||
+                       (contigmem_buffer_size & (contigmem_buffer_size - 1)) != 0) {
+               printf("buffer size 0x%x is not greater than PAGE_SIZE and "
+                               "power of two\n", contigmem_buffer_size);
+               return (EINVAL);
+       }
+
+       for (i = 0; i < contigmem_num_buffers; i++) {
+               contigmem_buffers[i] =
+                               contigmalloc(contigmem_buffer_size, M_CONTIGMEM, M_ZERO, 0,
+                       BUS_SPACE_MAXADDR, contigmem_buffer_size, 0);
+
+               if (contigmem_buffers[i] == NULL) {
+                       printf("contigmalloc failed for buffer %d\n", i);
+                       return (ENOMEM);
+               }
+
+               printf("%2u: virt=%p phys=%p\n", i, contigmem_buffers[i],
+                               (void *)pmap_kextract((vm_offset_t)contigmem_buffers[i]));
+
+               snprintf(index_string, sizeof(index_string), "%d", i);
+               snprintf(description, sizeof(description),
+                               "phys addr for buffer %d", i);
+               SYSCTL_ADD_PROC(NULL,
+                               &SYSCTL_NODE_CHILDREN(_hw_contigmem, physaddr), OID_AUTO,
+                               index_string, CTLTYPE_U64 | CTLFLAG_RD,
+                               (void *)(uintptr_t)i, 0, contigmem_physaddr, "LU",
+                               description);
+       }
+
+       contigmem_cdev = make_dev_credf(0, &contigmem_ops, 0, NULL, UID_ROOT,
+                       GID_WHEEL, 0600, "contigmem");
+
+       return (0);
+}
+
+static int
+contigmem_unload()
+{
+       int i;
+
+       if (contigmem_cdev != NULL)
+               destroy_dev(contigmem_cdev);
+
+       if (contigmem_eh_tag != NULL)
+               EVENTHANDLER_DEREGISTER(process_exit, contigmem_eh_tag);
+
+       for (i = 0; i < contigmem_num_buffers; i++)
+               if (contigmem_buffers[i] != NULL)
+                       contigfree(contigmem_buffers[i], contigmem_buffer_size,
+                                       M_CONTIGMEM);
+
+       return (0);
+}
+
+static int
+contigmem_physaddr(SYSCTL_HANDLER_ARGS)
+{
+       uint64_t        physaddr;
+       int             index = (int)(uintptr_t)arg1;
+
+       physaddr = (uint64_t)vtophys(contigmem_buffers[index]); 
+       return (sysctl_handle_64(oidp, &physaddr, 0, req));
+}
+
+static int
+contigmem_open(struct cdev *cdev, int fflags, int devtype,
+               struct thread *td)
+{
+       return (0);
+}
+
+static int
+contigmem_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
+               int prot, vm_memattr_t *memattr)
+{
+
+       *paddr = offset;
+       return (0);
+}
+
+static int
+contigmem_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
+               struct vm_object **obj, int nprot)
+{
+       /*
+        * The buffer index is encoded in the offset.  Divide the offset by
+        *  PAGE_SIZE to get the index of the buffer requested by the user
+        *  app.
+        */
+       if ((*offset/PAGE_SIZE) >= contigmem_num_buffers)
+               return (EINVAL);
+
+       *offset = (vm_ooffset_t)vtophys(contigmem_buffers[*offset/PAGE_SIZE]); 
+       *obj = vm_pager_allocate(OBJT_DEVICE, cdev, size, nprot, *offset,
+                       curthread->td_ucred);
+
+       return (0);
+}
+
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
new file mode 100644 (file)
index 0000000..73facae
--- /dev/null
@@ -0,0 +1,94 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_eal.a
+
+VPATH += $(RTE_SDK)/lib/librte_eal/common
+
+CFLAGS += -I$(SRCDIR)/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
+CFLAGS += -I$(RTE_SDK)/lib/librte_ring
+CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
+CFLAGS += -I$(RTE_SDK)/lib/librte_malloc
+CFLAGS += -I$(RTE_SDK)/lib/librte_ether
+CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_ring
+CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_pcap
+CFLAGS += $(WERROR_FLAGS) -O3
+
+# specific to linuxapp exec-env
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) := eal.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_memory.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_hugepage_info.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_thread.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_log.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_debug.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_lcore.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_timer.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_interrupts.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_alarm.c
+
+# from common dir
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_memzone.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_log.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_pci.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_memory.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_tailqs.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_errno.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_cpuflags.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_hexdump.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_whitelist.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_nonpci_devs.c
+
+CFLAGS_eal.o := -D_GNU_SOURCE
+#CFLAGS_eal_thread.o := -D_GNU_SOURCE
+CFLAGS_eal_log.o := -D_GNU_SOURCE
+CFLAGS_eal_common_log.o := -D_GNU_SOURCE
+
+# workaround for a gcc bug with noreturn attribute
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
+ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
+CFLAGS_eal_thread.o += -Wno-return-type
+CFLAGS_eal_hpet.o += -Wno-return-type
+endif
+
+INC := rte_per_lcore.h rte_lcore.h rte_interrupts.h rte_kni_common.h
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP)-include/exec-env := \
+       $(addprefix include/exec-env/,$(INC))
+
+DEPDIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += lib/librte_eal/common
+
+include $(RTE_SDK)/mk/rte.lib.mk
+
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
new file mode 100644 (file)
index 0000000..be00f91
--- /dev/null
@@ -0,0 +1,904 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <sys/file.h>
+#include <stddef.h>
+#include <errno.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_random.h>
+#include <rte_cycles.h>
+#include <rte_string_fns.h>
+#include <rte_cpuflags.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_version.h>
+#include <rte_atomic.h>
+#include <malloc_heap.h>
+#include <rte_eth_ring.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_hugepages.h"
+
+#define OPT_HUGE_DIR    "huge-dir"
+#define OPT_PROC_TYPE   "proc-type"
+#define OPT_NO_SHCONF   "no-shconf"
+#define OPT_NO_HPET     "no-hpet"
+#define OPT_VMWARE_TSC_MAP   "vmware-tsc-map"
+#define OPT_NO_PCI      "no-pci"
+#define OPT_NO_HUGE     "no-huge"
+#define OPT_FILE_PREFIX "file-prefix"
+#define OPT_SOCKET_MEM  "socket-mem"
+#define OPT_USE_DEVICE  "use-device"
+#define OPT_SYSLOG      "syslog"
+
+#define RTE_EAL_BLACKLIST_SIZE 0x100
+
+#define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
+
+#define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
+
+#define HIGHEST_RPL 3
+
+#define BITS_PER_HEX 4
+
+#define GET_BLACKLIST_FIELD(in, fd, lim, dlm)                   \
+{                                                               \
+       unsigned long val;                                      \
+       char *end;                                              \
+       errno = 0;                                              \
+       val = strtoul((in), &end, 16);                          \
+       if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+               return (-EINVAL);                               \
+       (fd) = (typeof (fd))val;                                \
+       (in) = end + 1;                                         \
+}
+
+/* Allow the application to print its usage message too if set */
+static rte_usage_hook_t        rte_application_usage_hook = NULL;
+/* early configuration structure, when memory config is not mmapped */
+static struct rte_mem_config early_mem_config;
+
+/* define fd variable here, because file needs to be kept open for the
+ * duration of the program, as we hold a write lock on it in the primary proc */
+static int mem_cfg_fd = -1;
+
+static struct flock wr_lock = {
+               .l_type = F_WRLCK,
+               .l_whence = SEEK_SET,
+               .l_start = offsetof(struct rte_mem_config, memseg),
+               .l_len = sizeof(early_mem_config.memseg),
+};
+
+/* Address of global and public configuration */
+static struct rte_config rte_config = {
+               .mem_config = &early_mem_config,
+};
+
+static struct rte_pci_addr eal_dev_blacklist[RTE_EAL_BLACKLIST_SIZE];
+
+/* internal configuration (per-core) */
+struct lcore_config lcore_config[RTE_MAX_LCORE];
+
+/* internal configuration */
+struct internal_config internal_config;
+
+/* used by rte_rdtsc() */
+int rte_cycles_vmware_tsc_map;
+
+/* Return a pointer to the configuration structure */
+struct rte_config *
+rte_eal_get_configuration(void)
+{
+       return &rte_config;
+}
+
+/* parse a sysfs (or other) file containing one integer value */
+int
+eal_parse_sysfs_value(const char *filename, unsigned long *val)
+{
+       FILE *f;
+       char buf[BUFSIZ];
+       char *end = NULL;
+
+       if ((f = fopen(filename, "r")) == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
+                       __func__, filename);
+               return -1;
+       }
+
+       if (fgets(buf, sizeof(buf), f) == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
+                       __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       *val = strtoul(buf, &end, 0);
+       if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+               RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
+                               __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       fclose(f);
+       return 0;
+}
+
+
+/* create memory configuration in shared/mmap memory. Take out
+ * a write lock on the memsegs, so we can auto-detect primary/secondary.
+ * This means we never close the file while running (auto-close on exit).
+ * We also don't lock the whole file, so that in future we can use read-locks
+ * on other parts, e.g. memzones, to detect if there are running secondary
+ * processes. */
+static void
+rte_eal_config_create(void)
+{
+       void *rte_mem_cfg_addr;
+       int retval;
+
+       const char *pathname = eal_runtime_config_path();
+
+       if (internal_config.no_shconf)
+               return;
+
+       if (mem_cfg_fd < 0){
+               mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
+               if (mem_cfg_fd < 0)
+                       rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+       }
+
+       retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
+       if (retval < 0){
+               close(mem_cfg_fd);
+               rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
+       }
+
+       retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
+       if (retval < 0){
+               close(mem_cfg_fd);
+               rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
+                               "process running?\n", pathname);
+       }
+
+       rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
+                               PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
+
+       if (rte_mem_cfg_addr == MAP_FAILED){
+               rte_panic("Cannot mmap memory for rte_config\n");
+       }
+       memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
+       rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* attach to an existing shared memory config */
+static void
+rte_eal_config_attach(void)
+{
+       void *rte_mem_cfg_addr;
+       const char *pathname = eal_runtime_config_path();
+
+       if (internal_config.no_shconf)
+               return;
+
+       if (mem_cfg_fd < 0){
+               mem_cfg_fd = open(pathname, O_RDWR);
+               if (mem_cfg_fd < 0)
+                       rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+       }
+
+       rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config), 
+                               PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
+       close(mem_cfg_fd);
+       if (rte_mem_cfg_addr == MAP_FAILED)
+               rte_panic("Cannot mmap memory for rte_config\n");
+
+       rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* Detect if we are a primary or a secondary process */
+static enum rte_proc_type_t
+eal_proc_type_detect(void)
+{
+       enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
+       const char *pathname = eal_runtime_config_path();
+
+       /* if we can open the file but not get a write-lock we are a secondary
+        * process. NOTE: if we get a file handle back, we keep that open
+        * and don't close it to prevent a race condition between multiple opens */
+       if (((mem_cfg_fd = open(pathname, O_RDWR)) >= 0) &&
+                       (fcntl(mem_cfg_fd, F_SETLK, &wr_lock) < 0))
+               ptype = RTE_PROC_SECONDARY;
+
+       RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
+                       ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
+
+       return ptype;
+}
+
+/* Sets up rte_config structure with the pointer to shared memory config.*/
+static void
+rte_config_init(void)
+{
+       /* set the magic in configuration structure */
+       rte_config.magic = RTE_MAGIC;
+       rte_config.process_type = (internal_config.process_type == RTE_PROC_AUTO) ?
+                       eal_proc_type_detect() : /* for auto, detect the type */
+                       internal_config.process_type; /* otherwise use what's already set */
+
+       switch (rte_config.process_type){
+       case RTE_PROC_PRIMARY:
+               rte_eal_config_create();
+               break;
+       case RTE_PROC_SECONDARY:
+               rte_eal_config_attach();
+               rte_eal_mcfg_wait_complete(rte_config.mem_config);
+               break;
+       case RTE_PROC_AUTO:
+       case RTE_PROC_INVALID:
+               rte_panic("Invalid process type\n");
+       }
+}
+
+/* display usage */
+static void
+eal_usage(const char *prgname)
+{
+       printf("\nUsage: %s -c COREMASK -n NUM [-m NB] [-r NUM] [-b <domain:bus:devid.func>]"
+              "[--proc-type primary|secondary|auto] \n\n"
+              "EAL options:\n"
+              "  -c COREMASK  : A hexadecimal bitmask of cores to run on\n"
+              "  -n NUM       : Number of memory channels\n"
+                  "  -v           : Display version information on startup\n"
+              "  -b <domain:bus:devid.func>: to prevent EAL from using specified "
+           "PCI device\n"
+              "                 (multiple -b options are allowed)\n"
+              "  -m MB        : memory to allocate\n"
+              "  -r NUM       : force number of memory ranks (don't detect)\n"
+              "  --"OPT_PROC_TYPE"  : type of this process\n"
+              "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only. "
+                          "Use comma-separate <[domain:]bus:devid.func> values.\n"
+              "               [NOTE: Cannot be used with -b option]\n"
+              "  --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
+                          "native RDTSC\n"
+              "\nEAL options for DEBUG use only:\n"
+              "  --"OPT_NO_HUGE"  : use malloc instead of hugetlbfs\n"
+              "  --"OPT_NO_PCI"   : disable pci\n"
+              "  --"OPT_NO_SHCONF": no shared config (mmap'd files)\n"
+              "\n",
+              prgname);
+       /* Allow the application to print its usage message too if hook is set */
+       if ( rte_application_usage_hook ) {
+               printf("===== Application Usage =====\n\n");
+               rte_application_usage_hook(prgname);
+       }
+}
+
+/* Set a per-application usage message */
+rte_usage_hook_t
+rte_set_application_usage_hook( rte_usage_hook_t usage_func )
+{
+       rte_usage_hook_t        old_func;
+
+       /* Will be NULL on the first call to denote the last usage routine. */
+       old_func                                        = rte_application_usage_hook;
+       rte_application_usage_hook      = usage_func;
+
+       return old_func;
+}
+
+/*
+ * Parse the coremask given as argument (hexadecimal string) and fill
+ * the global configuration (core role and core count) with the parsed
+ * value.
+ */
+static int xdigit2val(unsigned char c)
+{
+       int val;
+       if(isdigit(c)) 
+               val = c - '0';
+       else if(isupper(c))
+               val = c - 'A' + 10;
+       else 
+               val = c - 'a' + 10;
+       return val;
+}
+static int
+eal_parse_coremask(const char *coremask)
+{
+       struct rte_config *cfg = rte_eal_get_configuration();
+       int i, j, idx = 0 ;
+       unsigned count = 0;
+       char c;
+       int val;
+
+       if (coremask == NULL)
+               return -1;
+       /* Remove all blank characters ahead and after .
+        * Remove 0x/0X if exists.
+        */
+       while (isblank(*coremask))
+               coremask++;
+       if (coremask[0] == '0' && ((coremask[1] == 'x')
+               ||  (coremask[1] == 'X')) )
+               coremask += 2;
+       i = strnlen(coremask, sysconf(_SC_ARG_MAX));
+       while ((i > 0) && isblank(coremask[i - 1]))
+               i--;
+       if (i == 0)
+               return -1;
+
+       for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
+               c = coremask[i];
+               if (isxdigit(c) == 0) {
+                       /* invalid characters */
+                       return (-1);
+               }
+               val = xdigit2val(c);
+               for(j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) {
+                       if((1 << j) & val) {
+                               cfg->lcore_role[idx] = ROLE_RTE;
+                               if(count == 0)
+                                       cfg->master_lcore = idx;
+                               count++;
+                       } else  {
+                               cfg->lcore_role[idx] = ROLE_OFF;
+                       }
+               }
+       }
+       for(; i >= 0; i--)
+               if(coremask[i] != '0')
+                       return -1;
+       for(; idx < RTE_MAX_LCORE; idx++)
+               cfg->lcore_role[idx] = ROLE_OFF;
+       if(count == 0)
+               return -1;
+       return 0;
+}
+
+static int
+eal_parse_syslog(const char *facility)
+{
+       int i;
+       static struct {
+               const char *name;
+               int value;
+       } map[] = {
+               { "auth", LOG_AUTH },
+               { "cron", LOG_CRON },
+               { "daemon", LOG_DAEMON },
+               { "ftp", LOG_FTP },
+               { "kern", LOG_KERN },
+               { "lpr", LOG_LPR },
+               { "mail", LOG_MAIL },
+               { "news", LOG_NEWS },
+               { "syslog", LOG_SYSLOG },
+               { "user", LOG_USER },
+               { "uucp", LOG_UUCP },
+               { "local0", LOG_LOCAL0 },
+               { "local1", LOG_LOCAL1 },
+               { "local2", LOG_LOCAL2 },
+               { "local3", LOG_LOCAL3 },
+               { "local4", LOG_LOCAL4 },
+               { "local5", LOG_LOCAL5 },
+               { "local6", LOG_LOCAL6 },
+               { "local7", LOG_LOCAL7 },
+               { NULL, 0 }
+       };
+
+       for (i = 0; map[i].name; i++) {
+               if (!strcmp(facility, map[i].name)) {
+                       internal_config.syslog_facility = map[i].value;
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+static inline size_t
+eal_get_hugepage_mem_size(void)
+{
+       uint64_t size = 0;
+       unsigned i, j;
+
+       for (i = 0; i < internal_config.num_hugepage_sizes; i++) {
+               struct hugepage_info *hpi = &internal_config.hugepage_info[i];
+               if (hpi->hugedir != NULL) {
+                       for (j = 0; j < RTE_MAX_NUMA_NODES; j++) {
+                               size += hpi->hugepage_sz * hpi->num_pages[j];
+                       }
+               }
+       }
+
+       return (size < SIZE_MAX) ? (size_t)(size) : SIZE_MAX;
+}
+
+static enum rte_proc_type_t
+eal_parse_proc_type(const char *arg)
+{
+       if (strncasecmp(arg, "primary", sizeof("primary")) == 0)
+               return RTE_PROC_PRIMARY;
+       if (strncasecmp(arg, "secondary", sizeof("secondary")) == 0)
+               return RTE_PROC_SECONDARY;
+       if (strncasecmp(arg, "auto", sizeof("auto")) == 0)
+               return RTE_PROC_AUTO;
+
+       return RTE_PROC_INVALID;
+}
+
+static ssize_t
+eal_parse_blacklist_opt(const char *optarg, size_t idx)
+{
+       if (idx >= sizeof (eal_dev_blacklist) / sizeof (eal_dev_blacklist[0])) {
+               RTE_LOG(ERR, EAL, "%s - too many devices to blacklist...\n", optarg);
+               return (-EINVAL);
+       } else if (eal_parse_pci_DomBDF(optarg, eal_dev_blacklist + idx) < 0 &&
+                       eal_parse_pci_BDF(optarg, eal_dev_blacklist + idx) < 0) {
+               RTE_LOG(ERR, EAL, "%s - invalid device to blacklist...\n", optarg);
+               return (-EINVAL);
+       }
+
+       idx += 1;
+       return (idx);
+}
+
+/* Parse the argument given in the command line of the application */
+static int
+eal_parse_args(int argc, char **argv)
+{
+       int opt, ret, i;
+       char **argvopt;
+       int option_index;
+       int coremask_ok = 0;
+       ssize_t blacklist_index = 0;
+       char *prgname = argv[0];
+       static struct option lgopts[] = {
+               {OPT_NO_HUGE, 0, 0, 0},
+               {OPT_NO_PCI, 0, 0, 0},
+               {OPT_NO_HPET, 0, 0, 0},
+               {OPT_VMWARE_TSC_MAP, 0, 0, 0},
+               {OPT_HUGE_DIR, 1, 0, 0},
+               {OPT_NO_SHCONF, 0, 0, 0},
+               {OPT_PROC_TYPE, 1, 0, 0},
+               {OPT_FILE_PREFIX, 1, 0, 0},
+               {OPT_SOCKET_MEM, 1, 0, 0},
+               {OPT_USE_DEVICE, 1, 0, 0},
+               {OPT_SYSLOG, 1, NULL, 0},
+               {0, 0, 0, 0}
+       };
+
+       argvopt = argv;
+
+       internal_config.memory = 0;
+       internal_config.force_nrank = 0;
+       internal_config.force_nchannel = 0;
+       internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
+       internal_config.hugepage_dir = NULL;
+       internal_config.force_sockets = 0;
+       internal_config.syslog_facility = LOG_DAEMON;
+#ifdef RTE_LIBEAL_USE_HPET
+       internal_config.no_hpet = 0;
+#else
+       internal_config.no_hpet = 1;
+#endif
+       /* zero out the NUMA config */
+       for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
+               internal_config.socket_mem[i] = 0;
+
+       /* zero out hugedir descriptors */
+       for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
+               internal_config.hugepage_info[i].lock_descriptor = 0;
+
+       internal_config.vmware_tsc_map = 0;
+
+       while ((opt = getopt_long(argc, argvopt, "b:c:m:n:r:v",
+                                 lgopts, &option_index)) != EOF) {
+
+               switch (opt) {
+               /* blacklist */
+               case 'b':
+                       if ((blacklist_index = eal_parse_blacklist_opt(optarg,
+                           blacklist_index)) < 0) {
+                               eal_usage(prgname);
+                               return (-1);
+                       }
+                       break;
+               /* coremask */
+               case 'c':
+                       if (eal_parse_coremask(optarg) < 0) {
+                               RTE_LOG(ERR, EAL, "invalid coremask\n");
+                               eal_usage(prgname);
+                               return -1;
+                       }
+                       coremask_ok = 1;
+                       break;
+               /* size of memory */
+               case 'm':
+                       internal_config.memory = atoi(optarg);
+                       internal_config.memory *= 1024ULL;
+                       internal_config.memory *= 1024ULL;
+                       break;
+               /* force number of channels */
+               case 'n':
+                       internal_config.force_nchannel = atoi(optarg);
+                       if (internal_config.force_nchannel == 0 ||
+                           internal_config.force_nchannel > 4) {
+                               RTE_LOG(ERR, EAL, "invalid channel number\n");
+                               eal_usage(prgname);
+                               return -1;
+                       }
+                       break;
+               /* force number of ranks */
+               case 'r':
+                       internal_config.force_nrank = atoi(optarg);
+                       if (internal_config.force_nrank == 0 ||
+                           internal_config.force_nrank > 16) {
+                               RTE_LOG(ERR, EAL, "invalid rank number\n");
+                               eal_usage(prgname);
+                               return -1;
+                       }
+                       break;
+               case 'v':
+                       /* since message is explicitly requested by user, we
+                        * write message at highest log level so it can always be seen
+                        * even if info or warning messages are disabled */
+                       RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
+                       break;
+
+               /* long options */
+               case 0:
+                       if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) {
+                               internal_config.no_hugetlbfs = 1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) {
+                               internal_config.no_pci = 1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) {
+                               internal_config.no_hpet = 1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_VMWARE_TSC_MAP)) {
+                               internal_config.vmware_tsc_map = 1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) {
+                               internal_config.no_shconf = 1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) {
+                               RTE_LOG(ERR, EAL, "Option "OPT_HUGE_DIR" is not supported on"
+                                               "FreeBSD\n");
+                               return -1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) {
+                               internal_config.process_type = eal_parse_proc_type(optarg);
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) {
+                               RTE_LOG(ERR, EAL, "Option "OPT_FILE_PREFIX" is not supported on"
+                                               "FreeBSD\n");
+                               return -1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) {
+                               RTE_LOG(ERR, EAL, "Option "OPT_SOCKET_MEM" is not supported on"
+                                               "FreeBSD\n");
+                               return -1;
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
+                               eal_dev_whitelist_add_entry(optarg);
+                       }
+                       else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) {
+                               if (eal_parse_syslog(optarg) < 0) {
+                                       RTE_LOG(ERR, EAL, "invalid parameters for --"
+                                                       OPT_SYSLOG "\n");
+                                       eal_usage(prgname);
+                                       return -1;
+                               }
+                       }
+                       break;
+
+               default:
+                       eal_usage(prgname);
+                       return -1;
+               }
+       }
+
+       /* sanity checks */
+       if (!coremask_ok) {
+               RTE_LOG(ERR, EAL, "coremask not specified\n");
+               eal_usage(prgname);
+               return -1;
+       }
+       if (internal_config.process_type == RTE_PROC_AUTO){
+               internal_config.process_type = eal_proc_type_detect();
+       }
+       if (internal_config.process_type == RTE_PROC_INVALID){
+               RTE_LOG(ERR, EAL, "Invalid process type specified\n");
+               eal_usage(prgname);
+               return -1;
+       }
+       if (internal_config.process_type == RTE_PROC_PRIMARY &&
+                       internal_config.force_nchannel == 0) {
+               RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n");
+               eal_usage(prgname);
+               return -1;
+       }
+       if (index(internal_config.hugefile_prefix,'%') != NULL){
+               RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n");
+               eal_usage(prgname);
+               return -1;
+       }
+       if (internal_config.memory > 0 && internal_config.force_sockets == 1) {
+               RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified "
+                               "at the same time\n");
+               eal_usage(prgname);
+               return -1;
+       }
+       /* --no-huge doesn't make sense with either -m or --socket-mem */
+       if (internal_config.no_hugetlbfs &&
+                       (internal_config.memory > 0 ||
+                                       internal_config.force_sockets == 1)) {
+               RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified "
+                               "together with --no-huge!\n");
+               eal_usage(prgname);
+               return -1;
+       }
+
+       /* if no blacklist, parse a whitelist */
+       if (blacklist_index > 0) {
+               if (eal_dev_whitelist_exists()) {
+                       RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
+                                       "[--use-device] options cannot be used at the same time\n");
+                       eal_usage(prgname);
+                       return -1;
+               }
+               rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index);
+       } else {
+               if (eal_dev_whitelist_exists() && eal_dev_whitelist_parse() < 0) {
+                       RTE_LOG(ERR,EAL, "Error parsing whitelist[--use-device] options\n");
+                       return -1;
+               }
+       }
+
+       if (optind >= 0)
+               argv[optind-1] = prgname;
+
+       /* if no memory amounts were requested, this will result in 0 and
+        * will be overriden later, right after eal_hugepage_info_init() */
+       for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
+               internal_config.memory += internal_config.socket_mem[i];
+
+       ret = optind-1;
+       optind = 0; /* reset getopt lib */
+       return ret;
+}
+
+static void
+eal_check_mem_on_local_socket(void)
+{
+       const struct rte_memseg *ms;
+       int i, socket_id;
+
+       socket_id = rte_lcore_to_socket_id(rte_config.master_lcore);
+
+       ms = rte_eal_get_physmem_layout();
+
+       for (i = 0; i < RTE_MAX_MEMSEG; i++)
+               if (ms[i].socket_id == socket_id &&
+                               ms[i].len > 0)
+                       return;
+
+       RTE_LOG(WARNING, EAL, "WARNING: Master core has no "
+                       "memory on local socket!\n");
+}
+
+static int
+sync_func(__attribute__((unused)) void *arg)
+{
+       return 0;
+}
+
+inline static void 
+rte_eal_mcfg_complete(void)
+{
+       /* ALL shared mem_config related INIT DONE */
+       if (rte_config.process_type == RTE_PROC_PRIMARY)
+               rte_config.mem_config->magic = RTE_MAGIC;
+}
+
+/* Abstraction for port I/0 privilage */
+static int
+rte_eal_iopl_init(void)
+{
+       int fd = -1;
+       fd = open("/dev/io", O_RDWR);
+       if (fd < 0)
+               return -1;
+       return 0;
+}
+
+/* Launch threads, called at application init(). */
+int
+rte_eal_init(int argc, char **argv)
+{
+       int i, fctret, ret;
+       pthread_t thread_id;
+       static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
+
+       if (!rte_atomic32_test_and_set(&run_once))
+               return -1;
+
+       thread_id = pthread_self();
+
+       if (rte_eal_log_early_init() < 0)
+               rte_panic("Cannot init early logs\n");
+
+       fctret = eal_parse_args(argc, argv);
+       if (fctret < 0)
+               exit(1);
+
+       if (internal_config.no_hugetlbfs == 0 &&
+                       internal_config.process_type != RTE_PROC_SECONDARY &&
+                       eal_hugepage_info_init() < 0)
+               rte_panic("Cannot get hugepage information\n");
+
+       if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
+               if (internal_config.no_hugetlbfs)
+                       internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE;
+               else
+                       internal_config.memory = eal_get_hugepage_mem_size();
+       }
+
+       if (internal_config.vmware_tsc_map == 1) {
+#ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
+               rte_cycles_vmware_tsc_map = 1;
+               RTE_LOG (DEBUG, EAL, "Using VMWARE TSC MAP, "
+                               "you must have monitor_control.pseudo_perfctr = TRUE\n");
+#else
+               RTE_LOG (WARNING, EAL, "Ignoring --vmware-tsc-map because "
+                               "RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set\n");
+#endif
+       }
+
+       rte_srand(rte_rdtsc());
+
+       rte_config_init();
+
+       if (rte_eal_iopl_init() == 0)
+               rte_config.flags |= EAL_FLG_HIGH_IOPL;
+
+       if (rte_eal_cpu_init() < 0)
+               rte_panic("Cannot detect lcores\n");
+
+       if (rte_eal_memory_init() < 0)
+               rte_panic("Cannot init memory\n");
+
+       if (rte_eal_memzone_init() < 0)
+               rte_panic("Cannot init memzone\n");
+
+       if (rte_eal_tailqs_init() < 0)
+               rte_panic("Cannot init tail queues for objects\n");
+
+/*     if (rte_eal_log_init(argv[0], internal_config.syslog_facility) < 0)
+               rte_panic("Cannot init logs\n");*/
+
+       if (rte_eal_alarm_init() < 0)
+               rte_panic("Cannot init interrupt-handling thread\n");
+
+       if (rte_eal_intr_init() < 0)
+               rte_panic("Cannot init interrupt-handling thread\n");
+
+       if (rte_eal_timer_init() < 0)
+               rte_panic("Cannot init HPET or TSC timers\n");
+
+       if (rte_eal_pci_init() < 0)
+               rte_panic("Cannot init PCI\n");
+
+       RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%p)\n",
+               rte_config.master_lcore, thread_id);
+
+       eal_check_mem_on_local_socket();
+
+       rte_eal_mcfg_complete();
+
+       if (rte_eal_non_pci_ethdev_init() < 0)
+               rte_panic("Cannot init non-PCI eth_devs\n");
+
+       RTE_LCORE_FOREACH_SLAVE(i) {
+
+               /*
+                * create communication pipes between master thread
+                * and children
+                */
+               if (pipe(lcore_config[i].pipe_master2slave) < 0)
+                       rte_panic("Cannot create pipe\n");
+               if (pipe(lcore_config[i].pipe_slave2master) < 0)
+                       rte_panic("Cannot create pipe\n");
+
+               lcore_config[i].state = WAIT;
+
+               /* create a thread for each lcore */
+               ret = pthread_create(&lcore_config[i].thread_id, NULL,
+                                    eal_thread_loop, NULL);
+               if (ret != 0)
+                       rte_panic("Cannot create thread\n");
+       }
+
+       eal_thread_init_master(rte_config.master_lcore);
+
+       /*
+        * 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 fctret;
+}
+
+/* get core role */
+enum rte_lcore_role_t
+rte_eal_lcore_role(unsigned lcore_id)
+{
+       return (rte_config.lcore_role[lcore_id]);
+}
+
+enum rte_proc_type_t
+rte_eal_process_type(void)
+{
+       return (rte_config.process_type);
+}
+
diff --git a/lib/librte_eal/bsdapp/eal/eal_alarm.c b/lib/librte_eal/bsdapp/eal/eal_alarm.c
new file mode 100644 (file)
index 0000000..77d30f2
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+#include <stdlib.h>
+#include <errno.h>
+
+#include <rte_alarm.h>
+#include <rte_common.h>
+#include "eal_private.h"
+
+int
+rte_eal_alarm_init(void)
+{
+       return 0;
+}
+
+
+int
+rte_eal_alarm_set(uint64_t us __rte_unused, 
+               rte_eal_alarm_callback cb_fn __rte_unused, 
+               void *cb_arg __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn __rte_unused, 
+               void *cb_arg __rte_unused)
+{
+       return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_debug.c b/lib/librte_eal/bsdapp/eal/eal_debug.c
new file mode 100644 (file)
index 0000000..7dd3eb9
--- /dev/null
@@ -0,0 +1,113 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <execinfo.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_common.h>
+
+#define BACKTRACE_SIZE 256
+
+/* dump the stack of the calling core */
+void rte_dump_stack(void)
+{
+       void *func[BACKTRACE_SIZE];
+       char **symb = NULL;
+       int size;
+
+       size = backtrace(func, BACKTRACE_SIZE);
+       symb = backtrace_symbols(func, size);
+       while (size > 0) {
+               rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
+                       "%d: [%s]\n", size, symb[size - 1]);
+               size --;
+       }
+}
+
+/* not implemented in this environment */
+void rte_dump_registers(void)
+{
+       return;
+}
+
+/* call abort(), it will generate a coredump if enabled */
+void __rte_panic(const char *funcname, const char *format, ...)
+{
+       va_list ap;
+
+       /* disable history */
+       rte_log_set_history(0);
+
+       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);
+       rte_dump_stack();
+       rte_dump_registers();
+       abort();
+}
+
+/*
+ * Like rte_panic this terminates the application. However, no traceback is
+ * provided and no core-dump is generated.
+ */
+void
+rte_exit(int exit_code, const char *format, ...)
+{
+       va_list ap;
+
+       /* disable history */
+       rte_log_set_history(0);
+
+       if (exit_code != 0)
+               RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
+                               "  Cause: ", exit_code);
+
+       va_start(ap, format);
+       rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+       va_end(ap);
+
+#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR
+       exit(exit_code);
+#else
+       rte_dump_stack();
+       rte_dump_registers();
+       abort();
+#endif
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_hugepage_info.c b/lib/librte_eal/bsdapp/eal/eal_hugepage_info.c
new file mode 100644 (file)
index 0000000..dae3c8b
--- /dev/null
@@ -0,0 +1,133 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include <rte_log.h>
+#include <fcntl.h>
+#include "eal_hugepages.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+
+#define CONTIGMEM_DEV "/dev/contigmem"
+
+/*
+ * Uses mmap to create a shared memory area for storage of data
+ * Used in this file to store the hugepage file map on disk
+ */
+static void *
+create_shared_memory(const char *filename, const size_t mem_size)
+{
+       void *retval;
+       int fd = open(filename, O_CREAT | O_RDWR, 0666);
+       if (fd < 0)
+               return NULL;
+       if (ftruncate(fd, mem_size) < 0) {
+               close(fd);
+               return NULL;
+       }
+       retval = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       close(fd);
+       return retval;
+}
+
+/*
+ * No hugepage support on freebsd, but we dummy it, using contigmem driver
+ */
+int
+eal_hugepage_info_init(void)
+{
+       size_t sysctl_size;
+       int buffer_size, num_buffers, fd, error;
+       /* re-use the linux "internal config" structure for our memory data */
+       struct hugepage_info *hpi = &internal_config.hugepage_info[0];
+       struct hugepage_info *tmp_hpi;
+
+       sysctl_size = sizeof(num_buffers);
+       error = sysctlbyname("hw.contigmem.num_buffers", &num_buffers,
+                       &sysctl_size, NULL, 0);
+
+       if (error != 0) {
+               RTE_LOG(ERR, EAL, "could not read sysctl hw.contigmem.num_buffers");
+               return -1;
+       }
+
+       sysctl_size = sizeof(buffer_size);
+       error = sysctlbyname("hw.contigmem.buffer_size", &buffer_size,
+                       &sysctl_size, NULL, 0);
+
+       if (error != 0) {
+               RTE_LOG(ERR, EAL, "could not read sysctl hw.contigmem.buffer_size");
+               return -1;
+       }
+
+       fd = open(CONTIGMEM_DEV, O_RDWR);
+       if (fd < 0) {
+               RTE_LOG(ERR, EAL, "could not open "CONTIGMEM_DEV"\n");
+               return -1;
+       }
+
+       if (buffer_size >= 1<<30)
+               RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dGB\n",
+                               num_buffers, buffer_size>>30);
+       else if (buffer_size >= 1<<20)
+               RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dMB\n",
+                               num_buffers, buffer_size>>20);
+       else
+               RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dKB\n",
+                               num_buffers, buffer_size>>10);
+
+       internal_config.num_hugepage_sizes = 1;
+       hpi->hugedir = CONTIGMEM_DEV;
+       hpi->hugepage_sz = buffer_size;
+       hpi->num_pages[0] = num_buffers;
+       hpi->lock_descriptor = fd;
+       
+       tmp_hpi = create_shared_memory(eal_hugepage_info_path(),
+                                       sizeof(struct hugepage_info));
+       if (tmp_hpi == NULL ) {
+               RTE_LOG(ERR, EAL, "Failed to create shared memory!\n");
+               return -1;
+       }
+
+       memcpy(tmp_hpi, hpi, sizeof(struct hugepage_info));
+
+       if ( munmap(tmp_hpi, sizeof(struct hugepage_info)) < 0) {
+               RTE_LOG(ERR, EAL, "Failed to unmap shared memory!\n");
+               return -1;
+       }
+       
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_interrupts.c b/lib/librte_eal/bsdapp/eal/eal_interrupts.c
new file mode 100644 (file)
index 0000000..dafece5
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <rte_common.h>
+#include <rte_interrupts.h>
+#include "eal_private.h"
+
+int
+rte_intr_callback_register(struct rte_intr_handle *intr_handle __rte_unused,
+                       rte_intr_callback_fn cb __rte_unused, 
+                       void *cb_arg __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+rte_intr_callback_unregister(struct rte_intr_handle *intr_handle __rte_unused,
+                       rte_intr_callback_fn cb_fn __rte_unused, 
+                       void *cb_arg __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+rte_intr_enable(struct rte_intr_handle *intr_handle __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+rte_intr_disable(struct rte_intr_handle *intr_handle __rte_unused)
+{
+       return -ENOTSUP;
+}
+
+int
+rte_eal_intr_init(void)
+{
+       return 0;
+}
+
diff --git a/lib/librte_eal/bsdapp/eal/eal_lcore.c b/lib/librte_eal/bsdapp/eal/eal_lcore.c
new file mode 100644 (file)
index 0000000..e2f3793
--- /dev/null
@@ -0,0 +1,102 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <unistd.h>
+#include <sys/sysctl.h>
+
+#include <rte_log.h>
+#include <rte_eal.h>
+#include <rte_lcore.h>
+#include <rte_common.h>
+#include <rte_debug.h>
+
+#include "eal_private.h"
+
+/* No topology information available on FreeBSD including NUMA info */
+#define cpu_core_id(X) 0
+#define cpu_socket_id(X) 0
+
+static int
+get_ncpus(void)
+{
+       int mib[2] = {CTL_HW, HW_NCPU};
+       int ncpu;
+       size_t len = sizeof(ncpu);
+
+       sysctl(mib, 2, &ncpu, &len, NULL, 0);
+       RTE_LOG(INFO, EAL, "Sysctl reports %d cpus\n", ncpu);
+       return ncpu;
+}
+
+/*
+ * fill the cpu_info structure with as much info as we can get.
+ * code is similar to linux version, but sadly available info is less.
+ */
+int
+rte_eal_cpu_init(void)
+{
+       /* pointer to global configuration */
+       struct rte_config *config = rte_eal_get_configuration();
+       unsigned lcore_id;
+       unsigned count = 0;
+
+       const unsigned ncpus = get_ncpus();
+
+       /* disable lcores that were not detected */
+       RTE_LCORE_FOREACH(lcore_id) {
+
+               lcore_config[lcore_id].detected = (lcore_id < ncpus);
+               if (lcore_config[lcore_id].detected == 0) {
+                       RTE_LOG(DEBUG, EAL, "Skip lcore %u (not detected)\n", lcore_id);
+                       config->lcore_role[lcore_id] = ROLE_OFF;
+                       continue;
+               }
+               count++;
+               lcore_config[lcore_id].core_id = cpu_core_id(lcore_id);
+               lcore_config[lcore_id].socket_id = cpu_socket_id(lcore_id);
+               if (lcore_config[lcore_id].socket_id >= RTE_MAX_NUMA_NODES)
+#ifdef RTE_EAL_ALLOW_INV_SOCKET_ID
+                       lcore_config[lcore_id].socket_id = 0;
+#else
+                       rte_panic("Socket ID (%u) is greater than "
+                               "RTE_MAX_NUMA_NODES (%d)\n",
+                               lcore_config[lcore_id].socket_id, RTE_MAX_NUMA_NODES);
+#endif
+               RTE_LOG(DEBUG, EAL, "Detected lcore %u\n",
+                               lcore_id);
+       }
+
+       config->lcore_count = count;
+
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_log.c b/lib/librte_eal/bsdapp/eal/eal_log.c
new file mode 100644 (file)
index 0000000..55b7376
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/*
+ * set the log to default function, called during eal init process,
+ * once memzones are available.
+ */
+int
+rte_eal_log_init(const char *id __rte_unused, int facility __rte_unused)
+{
+       if (rte_eal_common_log_init(stderr) < 0)
+               return -1;
+       return 0;
+}
+
+int
+rte_eal_log_early_init(void)
+{
+       rte_openlog_stream(stderr);
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_memory.c b/lib/librte_eal/bsdapp/eal/eal_memory.c
new file mode 100644 (file)
index 0000000..7d2d269
--- /dev/null
@@ -0,0 +1,212 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <inttypes.h>
+#include <fcntl.h>
+
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include "eal_private.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+
+#define PAGE_SIZE (sysconf(_SC_PAGESIZE))
+
+static int
+rte_eal_contigmem_init(void)
+{
+       struct rte_mem_config *mcfg;
+       uint64_t total_mem = 0;
+       void *addr;
+       unsigned i, j, seg_idx = 0;
+
+       /* get pointer to global configuration */
+       mcfg = rte_eal_get_configuration()->mem_config;
+
+       /* for debug purposes, hugetlbfs can be disabled */
+       if (internal_config.no_hugetlbfs) {
+               addr = malloc(internal_config.memory);
+               mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr;
+               mcfg->memseg[0].addr = addr;
+               mcfg->memseg[0].len = internal_config.memory;
+               mcfg->memseg[0].socket_id = 0;
+               return 0;
+       }
+
+       /* map all hugepages and sort them */
+       for (i = 0; i < internal_config.num_hugepage_sizes; i ++){
+               struct hugepage_info *hpi;
+
+               hpi = &internal_config.hugepage_info[i];
+               for (j = 0; j < hpi->num_pages[0]; j++) {
+                       struct rte_memseg *seg;
+                       uint64_t physaddr;
+                       int error;
+                       size_t sysctl_size = sizeof(physaddr);
+                       char physaddr_str[64];
+
+                       addr = mmap(NULL, hpi->hugepage_sz, PROT_READ|PROT_WRITE,
+                                       MAP_SHARED, hpi->lock_descriptor, j * PAGE_SIZE);
+                       if (addr == MAP_FAILED) {
+                               RTE_LOG(ERR, EAL, "Failed to mmap buffer %u from %s\n",
+                                               j, hpi->hugedir);
+                               return -1;
+                       }
+
+                       rte_snprintf(physaddr_str, sizeof(physaddr_str), "hw.contigmem"
+                                       ".physaddr.%d", j);
+                       error = sysctlbyname(physaddr_str, &physaddr, &sysctl_size,
+                                       NULL, 0);
+                       if (error < 0) {
+                               RTE_LOG(ERR, EAL, "Failed to get physical addr for buffer %u "
+                                               "from %s\n", j, hpi->hugedir);
+                               return -1;
+                       }
+
+                       seg = &mcfg->memseg[seg_idx++];
+                       seg->addr = addr;
+                       seg->phys_addr = physaddr;
+                       seg->hugepage_sz = hpi->hugepage_sz;
+                       seg->len = hpi->hugepage_sz;
+                       seg->nchannel = mcfg->nchannel;
+                       seg->nrank = mcfg->nrank;
+                       seg->socket_id = 0;
+
+                       RTE_LOG(INFO, EAL, "Mapped memory segment %u @ %p: physaddr:0x%"
+                                       PRIx64", len %zu\n",
+                                       seg_idx, addr, physaddr, hpi->hugepage_sz);
+                       if (total_mem >= internal_config.memory ||
+                                       seg_idx >= RTE_MAX_MEMSEG)
+                               break;
+               }
+       }
+       return 0;
+}
+
+static int
+rte_eal_contigmem_attach(void)
+{
+       const struct hugepage_info *hpi;
+       int fd_hugepage_info, fd_hugepage = -1;
+       unsigned i = 0;
+       struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+    
+       /* Obtain a file descriptor for hugepage_info */
+       fd_hugepage_info = open(eal_hugepage_info_path(), O_RDONLY);
+       if (fd_hugepage_info < 0) {
+               RTE_LOG(ERR, EAL, "Could not open %s\n", eal_hugepage_info_path());
+               return -1;
+       }
+
+       /* Map the shared hugepage_info into the process address spaces */
+       hpi = mmap(NULL, sizeof(struct hugepage_info), PROT_READ, MAP_PRIVATE,
+                       fd_hugepage_info, 0);
+       if (hpi == NULL) {
+               RTE_LOG(ERR, EAL, "Could not mmap %s\n", eal_hugepage_info_path());
+               goto error;
+       }
+
+       /* Obtain a file descriptor for contiguous memory */
+       fd_hugepage = open(hpi->hugedir, O_RDWR);
+       if (fd_hugepage < 0) {
+               RTE_LOG(ERR, EAL, "Could not open %s\n", hpi->hugedir);
+               goto error;
+       }
+
+       /* Map the contiguous memory into each memory segment */
+       for (i = 0; i < hpi->num_pages[0]; i++) {
+
+               void *addr;
+               struct rte_memseg *seg = &mcfg->memseg[i];
+
+               addr = mmap(seg->addr, hpi->hugepage_sz, PROT_READ|PROT_WRITE,
+                               MAP_SHARED|MAP_FIXED, fd_hugepage, i * PAGE_SIZE);
+               if (addr == MAP_FAILED || addr != seg->addr) {
+                       RTE_LOG(ERR, EAL, "Failed to mmap buffer %u from %s\n",
+                               i, hpi->hugedir);
+                       goto error;
+               }
+        
+       }
+
+       /* hugepage_info is no longer required */
+       munmap((void *)(uintptr_t)hpi, sizeof(struct hugepage_info));
+       close(fd_hugepage_info);
+       close(fd_hugepage);
+       return 0;
+
+error:
+       if (fd_hugepage_info >= 0)
+               close(fd_hugepage_info);
+       if (fd_hugepage >= 0)
+               close(fd_hugepage);
+       return -1;
+}
+
+
+static int
+rte_eal_memdevice_init(void)
+{
+       struct rte_config *config;
+
+       if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+               return 0;
+
+       config = rte_eal_get_configuration();
+       config->mem_config->nchannel = internal_config.force_nchannel;
+       config->mem_config->nrank = internal_config.force_nrank;
+
+       return 0;
+}
+
+/* init memory subsystem */
+int
+rte_eal_memory_init(void)
+{
+       RTE_LOG(INFO, EAL, "Setting up physically contiguous memory...\n");
+       const int retval = rte_eal_process_type() == RTE_PROC_PRIMARY ?
+                       rte_eal_contigmem_init() :
+                       rte_eal_contigmem_attach();
+       if (retval < 0)
+               return -1;
+
+       if (internal_config.no_shconf == 0 && rte_eal_memdevice_init() < 0)
+               return -1;
+
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
new file mode 100644 (file)
index 0000000..7b04fa6
--- /dev/null
@@ -0,0 +1,519 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+
+#include "rte_pci_dev_ids.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+struct uio_map {
+       void *addr;
+       uint64_t offset;
+       uint64_t size;
+       uint64_t phaddr;
+};
+
+/*
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct uio_resource {
+       TAILQ_ENTRY(uio_resource) next;
+
+       struct rte_pci_addr pci_addr;
+       char path[PATH_MAX];
+       size_t nb_maps;
+       struct uio_map maps[PCI_MAX_RESOURCE];
+};
+
+TAILQ_HEAD(uio_res_list, uio_resource);
+
+static struct uio_res_list *uio_res_list = NULL;
+
+/* forward prototype of function called in pci_switch_module below */
+static int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/* map a particular resource from a file */
+static void *
+pci_map_resource(struct rte_pci_device *dev, void *requested_addr, 
+               const char *devname, off_t offset, size_t size)
+{
+       int fd;
+       void *mapaddr;
+
+       /*
+        * open devname, to mmap it
+        */
+       fd = open(devname, O_RDWR);
+       if (fd < 0) {
+               RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", 
+                       devname, strerror(errno));
+               goto fail;
+       }
+
+       /* Map the PCI memory resource of device */
+       mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+                       MAP_SHARED, fd, offset);
+       if (mapaddr == MAP_FAILED ||
+                       (requested_addr != NULL && mapaddr != requested_addr)) {
+               RTE_LOG(ERR, EAL, "%s(): cannot mmap(%s(%d), %p, 0x%lx, 0x%lx):"
+                       " %s (%p)\n", __func__, devname, fd, requested_addr, 
+                       (unsigned long)size, (unsigned long)offset,
+                       strerror(errno), mapaddr);
+               close(fd);
+               goto fail;
+       }
+
+       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+               /* save fd if in primary process */
+               dev->intr_handle.fd = fd;
+               dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+       } else {
+               /* fd is not needed in slave process, close it */
+               dev->intr_handle.fd = -1;
+               dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+               close(fd);
+       }
+
+       RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+       return mapaddr;
+
+fail:
+       dev->intr_handle.fd = -1;
+       dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+       return NULL;
+}
+
+#ifndef OFF_MAX
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+#endif
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+        size_t i;
+        struct uio_resource *uio_res;
+       TAILQ_FOREACH(uio_res, uio_res_list, next) {
+               /* skip this element if it doesn't match our PCI address */
+               if (memcmp(&uio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+                       continue;
+                
+               for (i = 0; i != uio_res->nb_maps; i++) {
+                       if (pci_map_resource(dev, uio_res->maps[i].addr,
+                                       uio_res->path,
+                                       (off_t)uio_res->maps[i].offset,
+                                       (size_t)uio_res->maps[i].size) != 
+                                       uio_res->maps[i].addr) {
+                               RTE_LOG(ERR, EAL,
+                                       "Cannot mmap device resource\n");
+                               return (-1);
+                       }
+               }
+               return (0);
+       }
+
+       RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+       return -1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+static int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+       int i, j;
+       char devname[PATH_MAX]; /* contains the /dev/uioX */
+       void *mapaddr;
+       uint64_t phaddr;
+       uint64_t offset;
+       uint64_t pagesz;
+       struct rte_pci_addr *loc = &dev->addr;
+       struct uio_resource *uio_res;
+       struct uio_map *maps;
+
+       dev->intr_handle.fd = -1;
+
+       rte_snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+                       dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+       if (access(devname, O_RDWR) < 0) {
+               RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+                               "skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+               return -1;
+       }
+
+       /* secondary processes - use already recorded details */
+       if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
+               (dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
+               return (pci_uio_map_secondary(dev));
+
+       if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
+               /* I/O port address already assigned */
+               /* rte_virtio_pmd does not need any other bar even if available */
+               return (0);
+       }
+       
+       /* allocate the mapping details for secondary processes*/
+       if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
+               RTE_LOG(ERR, EAL,
+                       "%s(): cannot store uio mmap details\n", __func__);
+               return (-1);
+       }
+
+       rte_snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
+       memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr));
+
+
+       /* Map all BARs */
+       pagesz = sysconf(_SC_PAGESIZE);
+       maps = uio_res->maps;
+       for (i = uio_res->nb_maps = 0; i != PCI_MAX_RESOURCE; i++) {
+
+               j = uio_res->nb_maps;
+               /* skip empty BAR */
+               if ((phaddr = dev->mem_resource[i].phys_addr) == 0)
+                       continue;
+               /* if matching map is found, then use it */
+               offset = i * pagesz;
+               maps[j].offset = offset;
+               maps[j].phaddr = dev->mem_resource[i].phys_addr;
+               maps[j].size = dev->mem_resource[i].len;
+               if (maps[j].addr != NULL ||
+                               (mapaddr = pci_map_resource(dev,
+                               NULL, devname, (off_t)offset,
+                               (size_t)maps[j].size)) == NULL) {
+                       rte_free(uio_res);
+                       return (-1);
+               }
+
+               maps[j].addr = mapaddr;
+               uio_res->nb_maps++;
+               dev->mem_resource[i].addr = mapaddr;
+       }
+
+       TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+       return (0);
+}
+
+/* parse the "resource" sysfs file */
+#define IORESOURCE_MEM  0x00000200
+
+/* Compare two PCI device addresses. */
+static int
+pci_addr_comparison(struct rte_pci_addr *addr, struct rte_pci_addr *addr2)
+{
+       uint64_t dev_addr = (addr->domain << 24) + (addr->bus << 16) + (addr->devid << 8) + addr->function;
+       uint64_t dev_addr2 = (addr2->domain << 24) + (addr2->bus << 16) + (addr2->devid << 8) + addr2->function;
+
+       if (dev_addr > dev_addr2)
+               return 1;
+       else
+               return 0;
+}
+
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+       struct rte_pci_device *dev;
+       struct pci_bar_io bar;
+       unsigned i, max;
+
+       dev = malloc(sizeof(*dev));
+       if (dev == NULL) {
+               return -1;
+       }
+
+       memset(dev, 0, sizeof(*dev));
+       dev->addr.domain = conf->pc_sel.pc_domain;
+       dev->addr.bus = conf->pc_sel.pc_bus;
+       dev->addr.devid = conf->pc_sel.pc_dev;
+       dev->addr.function = conf->pc_sel.pc_func;
+
+       /* get vendor id */
+       dev->id.vendor_id = conf->pc_vendor;
+
+       /* get device id */
+       dev->id.device_id = conf->pc_device;
+
+       /* get subsystem_vendor id */
+       dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+       /* get subsystem_device id */
+       dev->id.subsystem_device_id = conf->pc_subdevice;
+
+       /* TODO: get max_vfs */
+       dev->max_vfs = 0;
+
+       /* FreeBSD has no NUMA support (yet) */
+       dev->numa_node = 0;
+
+/* parse resources */
+       switch (conf->pc_hdr & PCIM_HDRTYPE) {
+       case PCIM_HDRTYPE_NORMAL:
+               max = PCIR_MAX_BAR_0;
+               break;
+       case PCIM_HDRTYPE_BRIDGE:
+               max = PCIR_MAX_BAR_1;
+               break;
+       case PCIM_HDRTYPE_CARDBUS:
+               max = PCIR_MAX_BAR_2;
+               break;
+       default:
+               goto skipdev;
+       }
+
+       for (i = 0; i <= max; i++) {
+               bar.pbi_sel = conf->pc_sel;
+               bar.pbi_reg = PCIR_BAR(i);
+               if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+                       continue;
+
+               dev->mem_resource[i].len = bar.pbi_length;
+               if (PCI_BAR_IO(bar.pbi_base)) {
+                       dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+                       continue;
+               }
+               dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+       }
+
+       /* device is valid, add in list (sorted) */
+       if (TAILQ_EMPTY(&device_list)) {
+               TAILQ_INSERT_TAIL(&device_list, dev, next);
+       }       
+       else {
+               struct rte_pci_device *dev2 = NULL;
+
+               TAILQ_FOREACH(dev2, &device_list, next) {
+                       if (pci_addr_comparison(&dev->addr, &dev2->addr))
+                               continue;
+                       else {
+                               TAILQ_INSERT_BEFORE(dev2, dev, next);
+                               return 0;
+                       }
+               }
+               TAILQ_INSERT_TAIL(&device_list, dev, next);
+       }
+                               
+       return 0;
+
+skipdev:
+       free(dev);
+       return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+static int
+pci_scan(void)
+{
+       int fd = -1;
+       unsigned dev_count = 0;
+       struct pci_conf matches[16];
+       struct pci_conf_io conf_io = {
+                       .pat_buf_len = 0,
+                       .num_patterns = 0,
+                       .patterns = NULL,
+                       .match_buf_len = sizeof(matches),
+                       .matches = &matches[0],
+       };
+
+       fd = open("/dev/pci", O_RDONLY);
+       if (fd < 0) {
+               RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+               goto error;
+       }
+
+       do {
+               unsigned i;
+               if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+                       RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+                                       __func__, strerror(errno));
+                       goto error;
+               }
+
+               for (i = 0; i < conf_io.num_matches; i++)
+                       if (pci_scan_one(fd, &matches[i]) < 0)
+                               goto error;
+
+               dev_count += conf_io.num_matches;
+       } while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+       close(fd);
+
+       RTE_LOG(ERR, EAL, "PCI scan found %u devices\n", dev_count);
+       return 0;
+
+error:
+       if (fd >= 0)
+               close(fd);
+       return -1;
+}
+
+/*
+ * If vendor/device ID match, call the devinit() function of the
+ * driver.
+ */
+int
+rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
+{
+       struct rte_pci_id *id_table;
+
+       for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
+
+               /* check if device's identifiers match the driver's ones */
+               if (id_table->vendor_id != dev->id.vendor_id &&
+                               id_table->vendor_id != PCI_ANY_ID)
+                       continue;
+               if (id_table->device_id != dev->id.device_id &&
+                               id_table->device_id != PCI_ANY_ID)
+                       continue;
+               if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
+                               id_table->subsystem_vendor_id != PCI_ANY_ID)
+                       continue;
+               if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
+                               id_table->subsystem_device_id != PCI_ANY_ID)
+                       continue;
+
+               struct rte_pci_addr *loc = &dev->addr;
+
+               RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+                               loc->domain, loc->bus, loc->devid, loc->function,
+                               dev->numa_node);
+
+               RTE_LOG(DEBUG, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+                               dev->id.device_id, dr->name);
+
+               /* no initialization when blacklisted, return without error */
+               if (dev->blacklisted) {
+                       RTE_LOG(DEBUG, EAL, "  Device is blacklisted, not initializing\n");
+                       return 0;
+               }
+
+               /* just map the NIC resources */
+               if (pci_uio_map_resource(dev) < 0)
+                       return -1;
+
+               /* We always should have BAR0 mapped */
+               if (rte_eal_process_type() == RTE_PROC_PRIMARY && 
+                       dev->mem_resource[0].addr == NULL) {
+                       RTE_LOG(ERR, EAL,
+                               "%s(): BAR0 is not mapped\n",
+                               __func__);
+                       return (-1);
+               }
+               /* reference driver structure */
+               dev->driver = dr;
+
+               /* call the driver devinit() function */
+               return dr->devinit(dr, dev);
+       }
+       /* return positive value if driver is not found */
+       return 1;
+}
+
+/* Init the PCI EAL subsystem */
+int
+rte_eal_pci_init(void)
+{
+       TAILQ_INIT(&driver_list);
+       TAILQ_INIT(&device_list);
+       uio_res_list = RTE_TAILQ_RESERVE_BY_IDX(RTE_TAILQ_PCI, uio_res_list);
+
+       /* for debug purposes, PCI can be disabled */
+       if (internal_config.no_pci)
+               return 0;
+
+       if (pci_scan() < 0) {
+               RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
+               return -1;
+       }
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_thread.c b/lib/librte_eal/bsdapp/eal/eal_thread.c
new file mode 100644 (file)
index 0000000..d2bec2e
--- /dev/null
@@ -0,0 +1,233 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sched.h>
+#include <pthread_np.h>
+#include <sys/queue.h>
+
+#include <rte_debug.h>
+#include <rte_atomic.h>
+#include <rte_launch.h>
+#include <rte_log.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_per_lcore.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+
+RTE_DEFINE_PER_LCORE(unsigned, _lcore_id);
+
+/*
+ * 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(int (*f)(void *), void *arg, unsigned 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;
+}
+
+/* set affinity for current thread */
+static int
+eal_thread_set_affinity(void)
+{
+       int s;
+       pthread_t thread;
+
+/*
+ * According to the section VERSIONS of the CPU_ALLOC man page:
+ *
+ * The CPU_ZERO(), CPU_SET(), CPU_CLR(), and CPU_ISSET() macros were added
+ * in glibc 2.3.3.
+ *
+ * CPU_COUNT() first appeared in glibc 2.6.
+ *
+ * CPU_AND(),     CPU_OR(),     CPU_XOR(),    CPU_EQUAL(),    CPU_ALLOC(),
+ * CPU_ALLOC_SIZE(), CPU_FREE(), CPU_ZERO_S(),  CPU_SET_S(),  CPU_CLR_S(),
+ * CPU_ISSET_S(),  CPU_AND_S(), CPU_OR_S(), CPU_XOR_S(), and CPU_EQUAL_S()
+ * first appeared in glibc 2.7.
+ */
+#if defined(CPU_ALLOC)
+       size_t size;
+       cpu_set_t *cpusetp;
+
+       cpusetp = CPU_ALLOC(RTE_MAX_LCORE);
+       if (cpusetp == NULL) {
+               RTE_LOG(ERR, EAL, "CPU_ALLOC failed\n");
+               return -1;
+       }
+
+       size = CPU_ALLOC_SIZE(RTE_MAX_LCORE);
+       CPU_ZERO_S(size, cpusetp);
+       CPU_SET_S(rte_lcore_id(), size, cpusetp);
+
+       thread = pthread_self();
+       s = pthread_setaffinity_np(thread, size, cpusetp);
+       if (s != 0) {
+               RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
+               CPU_FREE(cpusetp);
+               return -1;
+       }
+
+       CPU_FREE(cpusetp);
+#else /* CPU_ALLOC */
+       cpuset_t cpuset;
+       CPU_ZERO( &cpuset );
+       CPU_SET( rte_lcore_id(), &cpuset );
+
+       thread = pthread_self();
+       s = pthread_setaffinity_np(thread, sizeof( cpuset ), &cpuset);
+       if (s != 0) {
+               RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
+               return -1;
+       }
+#endif
+       return 0;
+}
+
+void eal_thread_init_master(unsigned lcore_id)
+{
+       /* set the lcore ID in per-lcore memory area */
+       RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+       /* set CPU affinity */
+       if (eal_thread_set_affinity() < 0)
+               rte_panic("cannot set affinity\n");
+}
+
+/* main loop of threads */
+__attribute__((noreturn)) void *
+eal_thread_loop(__attribute__((unused)) void *arg)
+{
+       char c;
+       int n, ret;
+       unsigned lcore_id;
+       pthread_t thread_id;
+       int m2s, s2m;
+
+       thread_id = pthread_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");
+
+       RTE_LOG(DEBUG, EAL, "Core %u is ready (tid=%p)\n",
+               lcore_id, thread_id);
+
+       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;
+
+       /* set CPU affinity */
+       if (eal_thread_set_affinity() < 0)
+               rte_panic("cannot set affinity\n");
+
+       /* 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();
+               lcore_config[lcore_id].state = FINISHED;
+       }
+
+       /* never reached */
+       /* pthread_exit(NULL); */
+       /* return NULL; */
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_timer.c b/lib/librte_eal/bsdapp/eal/eal_timer.c
new file mode 100644 (file)
index 0000000..b6cea17
--- /dev/null
@@ -0,0 +1,308 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_cycles.h>
+#include <rte_tailq.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_debug.h>
+
+#include "eal_private.h"
+#include "eal_internal_cfg.h"
+
+enum timer_source eal_timer_source = EAL_TIMER_HPET;
+
+/* The frequency of the RDTSC timer resolution */
+static uint64_t eal_tsc_resolution_hz = 0;
+
+#ifdef RTE_LIBEAL_USE_HPET
+
+#define DEV_HPET "/dev/hpet"
+
+/* Maximum number of counters. */
+#define HPET_TIMER_NUM 3
+
+/* General capabilities register */
+#define CLK_PERIOD_SHIFT     32 /* Clock period shift. */
+#define CLK_PERIOD_MASK      0xffffffff00000000ULL /* Clock period mask. */
+#define COUNT_SIZE_CAP_SHIFT 13 /* Count size capa. shift. */
+#define COUNT_SIZE_CAP_MASK 0x0000000000002000ULL /* Count size capa. mask. */
+
+/**
+ * HPET timer registers. From the Intel IA-PC HPET (High Precision Event
+ * Timers) Specification.
+ */
+struct eal_hpet_regs {
+       /* Memory-mapped, software visible registers */
+       uint64_t capabilities;      /**< RO General Capabilities Register. */
+       uint64_t reserved0;         /**< Reserved for future use. */
+       uint64_t config;            /**< RW General Configuration Register. */
+       uint64_t reserved1;         /**< Reserved for future use. */
+       uint64_t isr;               /**< RW Clear General Interrupt Status. */
+       uint64_t reserved2[25];     /**< Reserved for future use. */
+       union {
+               uint64_t counter;   /**< RW Main Counter Value Register. */
+               struct {
+                       uint32_t counter_l; /**< RW Main Counter Low. */
+                       uint32_t counter_h; /**< RW Main Counter High. */
+               };
+       };
+       uint64_t reserved3;         /**< Reserved for future use. */
+       struct {
+               uint64_t config;    /**< RW Timer Config and Capability Reg. */
+               uint64_t comp;      /**< RW Timer Comparator Value Register. */
+               uint64_t fsb;       /**< RW FSB Interrupt Route Register. */
+               uint64_t reserved4; /**< Reserved for future use. */
+       } timers[HPET_TIMER_NUM]; /**< Set of HPET timers. */
+};
+
+/* Mmap'd hpet registers */
+static volatile struct eal_hpet_regs *eal_hpet = NULL;
+
+/* Period at which the HPET counter increments in
+ * femtoseconds (10^-15 seconds). */
+static uint32_t eal_hpet_resolution_fs = 0;
+
+/* Frequency of the HPET counter in Hz */
+static uint64_t eal_hpet_resolution_hz = 0;
+
+/* Incremented 4 times during one 32bits hpet full count */
+static uint32_t eal_hpet_msb;
+
+static pthread_t msb_inc_thread_id;
+
+/*
+ * This function runs on a specific thread to update a global variable
+ * containing used to process MSB of the HPET (unfortunatelly, we need
+ * this because hpet is 32 bits by default under linux).
+ */
+static void
+hpet_msb_inc(__attribute__((unused)) void *arg)
+{
+       uint32_t t;
+
+       while (1) {
+               t = (eal_hpet->counter_l >> 30);
+               if (t != (eal_hpet_msb & 3))
+                       eal_hpet_msb ++;
+               sleep(10);
+       }
+}
+
+uint64_t
+rte_get_hpet_hz(void)
+{
+       if(internal_config.no_hpet)
+               rte_panic("Error, HPET called, but no HPET present\n");
+
+       return eal_hpet_resolution_hz;
+}
+
+uint64_t
+rte_get_hpet_cycles(void)
+{
+       uint32_t t, msb;
+       uint64_t ret;
+
+       if(internal_config.no_hpet)
+               rte_panic("Error, HPET called, but no HPET present\n");
+
+       t = eal_hpet->counter_l;
+       msb = eal_hpet_msb;
+       ret = (msb + 2 - (t >> 30)) / 4;
+       ret <<= 32;
+       ret += t;
+       return ret;
+}
+
+#endif
+
+
+void
+rte_delay_us(unsigned us)
+{
+       const uint64_t start = rte_get_timer_cycles();
+       const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6;
+       while ((rte_get_timer_cycles() - start) < ticks)
+               rte_pause();
+}
+
+uint64_t
+rte_get_tsc_hz(void)
+{
+       return eal_tsc_resolution_hz;
+}
+
+
+#ifdef RTE_LIBEAL_USE_HPET
+/*
+ * Open and mmap /dev/hpet (high precision event timer) that will
+ * provide our time reference.
+ */
+int
+rte_eal_hpet_init(int make_default)
+{
+       int fd, ret;
+
+       if (internal_config.no_hpet) {
+               RTE_LOG(INFO, EAL, "HPET is disabled\n");
+               return -1;
+       }
+
+       fd = open(DEV_HPET, O_RDONLY);
+       if (fd < 0) {
+               RTE_LOG(ERR, EAL, "ERROR: Cannot open "DEV_HPET": %s!\n",
+                       strerror(errno));
+               internal_config.no_hpet = 1;
+               return -1;
+       }
+       eal_hpet = mmap(NULL, 1024, PROT_READ, MAP_SHARED, fd, 0);
+       if (eal_hpet == MAP_FAILED) {
+               RTE_LOG(ERR, EAL, "ERROR: Cannot mmap "DEV_HPET"!\n"
+                               "Please enable CONFIG_HPET_MMAP in your kernel configuration "
+                               "to allow HPET support.\n"
+                               "To run without using HPET, set CONFIG_RTE_LIBEAL_USE_HPET=n "
+                               "in your build configuration or use '--no-hpet' EAL flag.\n");
+               close(fd);
+               internal_config.no_hpet = 1;
+               return -1;
+       }
+       close(fd);
+
+       eal_hpet_resolution_fs = (uint32_t)((eal_hpet->capabilities &
+                                       CLK_PERIOD_MASK) >>
+                                       CLK_PERIOD_SHIFT);
+
+       eal_hpet_resolution_hz = (1000ULL*1000ULL*1000ULL*1000ULL*1000ULL) /
+               (uint64_t)eal_hpet_resolution_fs;
+
+       RTE_LOG(INFO, EAL, "HPET frequency is ~%"PRIu64" kHz\n",
+                       eal_hpet_resolution_hz/1000);
+
+       eal_hpet_msb = (eal_hpet->counter_l >> 30);
+
+       /* create a thread that will increment a global variable for
+        * msb (hpet is 32 bits by default under linux) */
+       ret = pthread_create(&msb_inc_thread_id, NULL,
+                       (void *(*)(void *))hpet_msb_inc, NULL);
+       if (ret < 0) {
+               RTE_LOG(ERR, EAL, "ERROR: Cannot create HPET timer thread!\n");
+               internal_config.no_hpet = 1;
+               return -1;
+       }
+
+       if (make_default)
+               eal_timer_source = EAL_TIMER_HPET;
+       return 0;
+}
+#endif
+
+static int
+set_tsc_freq_from_clock(void)
+{
+#ifdef CLOCK_MONOTONIC_RAW
+#define NS_PER_SEC 1E9
+
+       struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
+
+       struct timespec t_start, t_end;
+
+       if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) {
+               uint64_t ns, end, start = rte_rdtsc();
+               nanosleep(&sleeptime,NULL);
+               clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
+               end = rte_rdtsc();
+               ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
+               ns += (t_end.tv_nsec - t_start.tv_nsec);
+
+               double secs = (double)ns/NS_PER_SEC;
+               eal_tsc_resolution_hz = (uint64_t)((end - start)/secs);
+               return 0;
+       }
+#endif
+       return -1;
+}
+
+static void
+set_tsc_freq_fallback(void)
+{
+       RTE_LOG(WARNING, EAL, "WARNING: clock_gettime cannot use "
+                       "CLOCK_MONOTONIC_RAW and HPET is not available"
+                       " - clock timings may be less accurate.\n");
+       /* assume that the sleep(1) will sleep for 1 second */
+       uint64_t start = rte_rdtsc();
+       sleep(1);
+       eal_tsc_resolution_hz = rte_rdtsc() - start;
+}
+/*
+ * This function measures the TSC frequency. It uses a variety of approaches.
+ *
+ * 1. If kernel provides CLOCK_MONOTONIC_RAW we use that to tune the TSC value
+ * 2. If kernel does not provide that, and we have HPET support, tune using HPET
+ * 3. Lastly, if neither of the above can be used, just sleep for 1 second and
+ * tune off that, printing a warning about inaccuracy of timing
+ */
+static void
+set_tsc_freq(void)
+{
+       if (set_tsc_freq_from_clock() < 0)
+               set_tsc_freq_fallback();
+
+       RTE_LOG(INFO, EAL, "TSC frequency is ~%"PRIu64" KHz\n",
+                       eal_tsc_resolution_hz/1000);
+}
+
+int
+rte_eal_timer_init(void)
+{
+
+       eal_timer_source = EAL_TIMER_TSC;
+
+       set_tsc_freq();
+       return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/include/eal_filesystem.h b/lib/librte_eal/bsdapp/eal/include/eal_filesystem.h
new file mode 100644 (file)
index 0000000..034e58d
--- /dev/null
@@ -0,0 +1,118 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+/**
+ * @file
+ * Stores functions and path defines for files and directories
+ * on the filesystem for Linux, that are used by the Linux EAL.
+ */
+
+#ifndef _EAL_LINUXAPP_FILESYSTEM_H
+#define _EAL_LINUXAPP_FILESYSTEM_H
+
+/** Path of rte config file. */
+#define RUNTIME_CONFIG_FMT "%s/.%s_config"
+
+#include <stdint.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <rte_string_fns.h>
+#include "eal_internal_cfg.h"
+
+static const char *default_config_dir = "/var/run";
+
+static inline const char *
+eal_runtime_config_path(void)
+{
+       static char buffer[PATH_MAX]; /* static so auto-zeroed */
+       const char *directory = default_config_dir;
+       const char *home_dir = getenv("HOME");
+
+       if (getuid() != 0 && home_dir != NULL)
+               directory = home_dir;
+       rte_snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT, directory,
+                       internal_config.hugefile_prefix);
+       return buffer;
+}
+
+/** Path of hugepage info file. */
+#define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
+
+static inline const char *
+eal_hugepage_info_path(void)
+{
+       static char buffer[PATH_MAX]; /* static so auto-zeroed */
+       const char *directory = default_config_dir;
+       const char *home_dir = getenv("HOME");
+
+       if (getuid() != 0 && home_dir != NULL)
+               directory = home_dir;
+       rte_snprintf(buffer, sizeof(buffer) - 1, HUGEPAGE_INFO_FMT, directory,
+                       internal_config.hugefile_prefix);
+       return buffer;
+}
+
+/** String format for hugepage map files. */
+#define HUGEFILE_FMT "%s/%smap_%d"
+#define TEMP_HUGEFILE_FMT "%s/%smap_temp_%d"
+
+static inline const char *
+eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
+{
+       rte_snprintf(buffer, buflen, HUGEFILE_FMT, hugedir,
+                       internal_config.hugefile_prefix, f_id);
+       buffer[buflen - 1] = '\0';
+       return buffer;
+}
+
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+static inline const char *
+eal_get_hugefile_temp_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
+{
+       rte_snprintf(buffer, buflen, TEMP_HUGEFILE_FMT, hugedir,
+                       internal_config.hugefile_prefix, f_id);
+       buffer[buflen - 1] = '\0';
+       return buffer;
+}
+#endif
+
+/** define the default filename prefix for the %s values above */
+#define HUGEFILE_PREFIX_DEFAULT "rte"
+
+/** Function to read a single numeric value from a file on the filesystem.
+ * Used to read information from files on /sys */
+int eal_parse_sysfs_value(const char *filename, unsigned long *val);
+
+#endif /* _EAL_LINUXAPP_FILESYSTEM_H */
diff --git a/lib/librte_eal/bsdapp/eal/include/eal_hugepages.h b/lib/librte_eal/bsdapp/eal/include/eal_hugepages.h
new file mode 100644 (file)
index 0000000..064cdb0
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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 RTE_LINUXAPP_HUGEPAGES_H_
+#define RTE_LINUXAPP_HUGEPAGES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define MAX_HUGEPAGE_PATH PATH_MAX
+
+/**
+ * Structure used to store informations about hugepages that we mapped
+ * through the files in hugetlbfs.
+ */
+struct hugepage_file {
+       void *orig_va;      /**< virtual addr of first mmap() */
+       void *final_va;     /**< virtual addr of 2nd mmap() */
+       uint64_t physaddr;  /**< physical addr */
+       size_t size;        /**< the page size */
+       int socket_id;      /**< NUMA socket ID */
+       int file_id;        /**< the '%d' in HUGEFILE_FMT */
+       int memseg_id;      /**< the memory segment to which page belongs */
+#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
+       int repeated;           /**< number of times the page size is repeated */
+#endif
+       char filepath[MAX_HUGEPAGE_PATH]; /**< path to backing file on filesystem */
+};
+
+/**
+ * Read the information from linux on what hugepages are available
+ * for the EAL to use
+ */
+int eal_hugepage_info_init(void);
+
+#endif /* EAL_HUGEPAGES_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/eal_internal_cfg.h b/lib/librte_eal/bsdapp/eal/include/eal_internal_cfg.h
new file mode 100644 (file)
index 0000000..643db7c
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+
+/**
+ * @file
+ * Holds the structures for the eal internal configuration
+ */
+
+#ifndef _EAL_LINUXAPP_INTERNAL_CFG
+#define _EAL_LINUXAPP_INTERNAL_CFG
+
+#include <rte_eal.h>
+
+#define MAX_HUGEPAGE_SIZES 3  /**< support up to 3 page sizes */
+
+/*
+ * internal configuration structure for the number, size and
+ * mount points of hugepages
+ */
+struct hugepage_info {
+       size_t hugepage_sz;   /**< size of a huge page */
+       const char *hugedir;    /**< dir where hugetlbfs is mounted */
+       uint32_t num_pages[RTE_MAX_NUMA_NODES];
+                               /**< number of hugepages of that size on each socket */
+       int lock_descriptor;    /**< file descriptor for hugepage dir */
+};
+
+/**
+ * internal configuration
+ */
+struct internal_config {
+       volatile size_t memory;           /**< amount of asked memory */
+       volatile unsigned force_nchannel; /**< force number of channels */
+       volatile unsigned force_nrank;    /**< force number of ranks */
+       volatile unsigned no_hugetlbfs;   /**< true to disable hugetlbfs */
+       volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
+       volatile unsigned no_pci;         /**< true to disable PCI */
+       volatile unsigned no_hpet;        /**< true to disable HPET */
+       volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
+                                                                               * instead of native TSC */
+       volatile unsigned no_shconf;      /**< true if there is no shared config */
+       volatile enum rte_proc_type_t process_type; /* multi-process proc type */
+       /* true to try allocating memory on specific sockets */
+       volatile unsigned force_sockets;
+       volatile uint64_t socket_mem[RTE_MAX_NUMA_NODES]; /**< amount of memory per socket */
+       uintptr_t base_virtaddr;          /**< base address to try and reserve memory from */
+       volatile int syslog_facility;     /**< facility passed to openlog() */
+       const char *hugefile_prefix;      /**< the base filename of hugetlbfs files */
+       const char *hugepage_dir;         /**< specific hugetlbfs directory to use */
+
+       unsigned num_hugepage_sizes;      /**< how many sizes on this system */
+       struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
+};
+extern struct internal_config internal_config; /**< Global EAL configuration. */
+
+#endif
diff --git a/lib/librte_eal/bsdapp/eal/include/eal_thread.h b/lib/librte_eal/bsdapp/eal/include/eal_thread.h
new file mode 100644 (file)
index 0000000..c21b4b0
--- /dev/null
@@ -0,0 +1,53 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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 _EAL_LINUXAPP_THREAD_H_
+#define _EAL_LINUXAPP_THREAD_H_
+
+/**
+ * basic loop of thread, called for each thread by eal_init().
+ *
+ * @param arg
+ *   opaque pointer
+ */
+__attribute__((noreturn)) void *eal_thread_loop(void *arg);
+
+/**
+ * Init per-lcore info for master thread
+ *
+ * @param lcore_id
+ *   identifier of master lcore
+ */
+void eal_thread_init_master(unsigned lcore_id);
+
+#endif /* _EAL_LINUXAPP_PRIVATE_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
new file mode 100644 (file)
index 0000000..ea05d58
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ *   This file is provided under a dual BSD/LGPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ * 
+ *   GNU LESSER GENERAL PUBLIC LICENSE
+ * 
+ *   Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
+ * 
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2.1 of the GNU Lesser General Public License
+ *   as published by the Free Software Foundation.
+ * 
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ * 
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ *   Contact Information:
+ *   Intel Corporation
+ * 
+ * 
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *    OWNER 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 _RTE_DOM0_COMMON_H_
+#define _RTE_DOM0_COMMON_H_
+
+#ifdef __KERNEL__
+#include <linux/if.h>
+#endif
+
+#define DOM0_NAME_MAX   256 
+#define DOM0_MM_DEV   "/dev/dom0_mm"
+
+#define DOM0_CONTIG_NUM_ORDER       9       /**< 2M order */
+#define DOM0_NUM_MEMSEG             512     /**< Maximum nb. of memory segment. */ 
+#define DOM0_MEMBLOCK_SIZE          0x200000 /**< Maximum nb. of memory block(2M). */
+#define DOM0_CONFIG_MEMSIZE         4096     /**< Maximum config memory size(4G). */
+#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
+
+#define RTE_DOM0_IOCTL_PREPARE_MEMSEG    _IOWR(0, 1 , struct memory_info)
+#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG  _IOWR(0, 2 , char *)
+#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG    _IOWR(0, 3, int)
+#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO   _IOWR(0, 4, void *)
+
+/**
+ * A structure used to store memory information. 
+ */
+struct memory_info {
+       char name[DOM0_NAME_MAX];
+       uint64_t size;
+};
+
+/**
+ * A structure used to store memory segment information.
+ */
+struct memseg_info {
+       uint32_t idx;
+       uint64_t pfn;
+       uint64_t size;
+       uint64_t mfn[DOM0_NUM_MEMBLOCK];
+};
+
+/**
+ * A structure used to store memory block information. 
+ */
+struct memblock_info {
+       uint8_t  exchange_flag;
+       uint64_t vir_addr;
+       uint64_t pfn;
+       uint64_t mfn;
+};
+#endif /* _RTE_DOM0_COMMON_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h
new file mode 100644 (file)
index 0000000..6733948
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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 _RTE_INTERRUPTS_H_
+#error "don't include this file directly, please include generic <rte_interrupts.h>"
+#endif
+
+#ifndef _RTE_LINUXAPP_INTERRUPTS_H_
+#define _RTE_LINUXAPP_INTERRUPTS_H_
+
+enum rte_intr_handle_type {
+       RTE_INTR_HANDLE_UNKNOWN = 0,
+       RTE_INTR_HANDLE_UIO,      /**< uio device handle */
+       RTE_INTR_HANDLE_ALARM,    /**< alarm handle */
+       RTE_INTR_HANDLE_MAX
+};
+
+/** Handle for interrupts. */
+struct rte_intr_handle {
+       int fd;                          /**< file descriptor */
+       enum rte_intr_handle_type type;  /**< handle type */
+};
+
+#endif /* _RTE_LINUXAPP_INTERRUPTS_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_kni_common.h
new file mode 100755 (executable)
index 0000000..ad73feb
--- /dev/null
@@ -0,0 +1,166 @@
+/*-
+ *   This file is provided under a dual BSD/LGPLv2 license.  When using or
+ *   redistributing this file, you may do so under either license.
+ * 
+ *   GNU LESSER GENERAL PUBLIC LICENSE
+ * 
+ *   Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
+ * 
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of version 2.1 of the GNU Lesser General Public License
+ *   as published by the Free Software Foundation.
+ * 
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ * 
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ *   Contact Information:
+ *   Intel Corporation
+ * 
+ * 
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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.
+ *   * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *    OWNER 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 _RTE_KNI_COMMON_H_
+#define _RTE_KNI_COMMON_H_
+
+#ifdef __KERNEL__
+#include <linux/if.h>
+#endif
+
+/**
+ * KNI name is part of memzone name.
+ */
+#define RTE_KNI_NAMESIZE 32
+
+/*
+ * Request id.
+ */
+enum rte_kni_req_id {
+       RTE_KNI_REQ_UNKNOWN = 0,
+       RTE_KNI_REQ_CHANGE_MTU,
+       RTE_KNI_REQ_CFG_NETWORK_IF,
+       RTE_KNI_REQ_MAX,
+};
+
+/*
+ * Structure for KNI request.
+ */
+struct rte_kni_request {
+       uint32_t req_id;             /**< Request id */
+       union {
+               uint32_t new_mtu;    /**< New MTU */
+               uint8_t if_up;       /**< 1: interface up, 0: interface down */
+       };
+       int32_t result;               /**< Result for processing request */
+} __attribute__((__packed__));
+
+/*
+ * Fifo struct mapped in a shared memory. It describes a circular buffer FIFO
+ * Write and read should wrap arround. Fifo is empty when write == read
+ * Writing should never overwrite the read position
+ */
+struct rte_kni_fifo {
+       volatile unsigned write;     /**< Next position to be written*/
+       volatile unsigned read;      /**< Next position to be read */
+       unsigned len;                /**< Circular buffer length */
+       unsigned elem_size;          /**< Pointer size - for 32/64 bit OS */
+       void * volatile buffer[0];   /**< The buffer contains mbuf pointers */
+};
+
+/*
+ * The kernel image of the rte_mbuf struct, with only the relevant fields.
+ * Padding is necessary to assure the offsets of these fields
+ */
+struct rte_kni_mbuf {
+       void *pool;
+       void *buf_addr;
+       char pad0[14];
+       uint16_t ol_flags;      /**< Offload features. */
+       void *next;
+       void *data;             /**< Start address of data in segment buffer. */
+       uint16_t data_len;      /**< Amount of data in segment buffer. */
+       char pad2[2];
+       uint16_t pkt_len;       /**< Total pkt len: sum of all segment data_len. */
+} __attribute__((__aligned__(64)));
+
+/*
+ * Struct used to create a KNI device. Passed to the kernel in IOCTL call
+ */
+
+struct rte_kni_device_info {
+       char name[RTE_KNI_NAMESIZE];  /**< Network device name for KNI */
+
+       phys_addr_t tx_phys;
+       phys_addr_t rx_phys;
+       phys_addr_t alloc_phys;
+       phys_addr_t free_phys;
+
+       /* Used by Ethtool */
+       phys_addr_t req_phys;
+       phys_addr_t resp_phys;
+       phys_addr_t sync_phys;
+       void * sync_va;
+
+       /* mbuf mempool */
+       void * mbuf_va;
+       phys_addr_t mbuf_phys;
+
+       /* PCI info */
+       uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+       uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+       uint8_t bus;                  /**< Device bus */
+       uint8_t devid;                /**< Device ID */
+       uint8_t function;             /**< Device function. */
+
+       uint16_t group_id;            /**< Group ID */
+       uint32_t core_id;             /**< core ID to bind for kernel thread */
+
+       uint8_t force_bind : 1;       /**< Flag for kernel thread binding */
+
+       /* mbuf size */
+       unsigned mbuf_size;
+};
+
+#define KNI_DEVICE "kni"
+
+#define RTE_KNI_IOCTL_TEST    _IOWR(0, 1, int)
+#define RTE_KNI_IOCTL_CREATE  _IOWR(0, 2, struct rte_kni_device_info)
+#define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info)
+
+#endif /* _RTE_KNI_COMMON_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_lcore.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_lcore.h
new file mode 100644 (file)
index 0000000..57499b7
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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 _RTE_LCORE_H_
+#error "don't include this file directly, please include generic <rte_lcore.h>"
+#endif
+
+#ifndef _RTE_LINUXAPP_LCORE_H_
+#define _RTE_LINUXAPP_LCORE_H_
+
+/**
+ * @file
+ * API for lcore and socket manipulation in linuxapp environment
+ */
+
+/**
+ * structure storing internal configuration (per-lcore)
+ */
+struct lcore_config {
+       unsigned detected;         /**< true if lcore was detected */
+       pthread_t thread_id;       /**< pthread identifier */
+       int pipe_master2slave[2];  /**< communication pipe with master */
+       int pipe_slave2master[2];  /**< communication pipe with master */
+       lcore_function_t * volatile f;         /**< function to call */
+       void * volatile arg;       /**< argument of function */
+       volatile int ret;          /**< return value of function */
+       volatile enum rte_lcore_state_t state; /**< lcore state */
+       unsigned socket_id;        /**< physical socket id for this lcore */
+       unsigned core_id;          /**< core number on socket for this lcore */
+};
+
+/**
+ * internal configuration (per-lcore)
+ */
+extern struct lcore_config lcore_config[RTE_MAX_LCORE];
+
+#endif /* _RTE_LINUXAPP_LCORE_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_per_lcore.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_per_lcore.h
new file mode 100644 (file)
index 0000000..173c634
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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 _RTE_PER_LCORE_H_
+#error "don't include this file directly, please include generic <rte_per_lcore.h>"
+#endif
+
+#ifndef _RTE_LINUXAPP_PER_LCORE_H_
+#define _RTE_LINUXAPP_PER_LCORE_H_
+
+/**
+ * @file
+ * Per-lcore variables in RTE on linuxapp environment
+ */
+
+#include <pthread.h>
+
+/**
+ * Macro to define a per lcore variable "var" of type "type", don't
+ * use keywords like "static" or "volatile" in type, just prefix the
+ * whole macro.
+ */
+#define RTE_DEFINE_PER_LCORE(type, name)                       \
+       __thread __typeof__(type) per_lcore_##name
+
+/**
+ * Macro to declare an extern per lcore variable "var" of type "type"
+ */
+#define RTE_DECLARE_PER_LCORE(type, name)                      \
+       extern __thread __typeof__(type) per_lcore_##name
+
+/**
+ * Read/write the per-lcore variable value
+ */
+#define RTE_PER_LCORE(name) (per_lcore_##name)
+
+#endif /* _RTE_LINUXAPP_PER_LCORE_H_ */
diff --git a/lib/librte_eal/bsdapp/nic_uio/BSDmakefile b/lib/librte_eal/bsdapp/nic_uio/BSDmakefile
new file mode 100644 (file)
index 0000000..ef3929b
--- /dev/null
@@ -0,0 +1,36 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+#
+
+KMOD=  nic_uio
+SRCS=  nic_uio.c device_if.h bus_if.h pci_if.h
+
+.include <bsd.kmod.mk>
diff --git a/lib/librte_eal/bsdapp/nic_uio/Makefile b/lib/librte_eal/bsdapp/nic_uio/Makefile
new file mode 100644 (file)
index 0000000..60094dc
--- /dev/null
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# module name and path
+#
+MODULE = nic_uio
+
+#
+# CFLAGS
+#
+MODULE_CFLAGS += -I$(SRCDIR) 
+MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
+MODULE_CFLAGS += -Winline -Wall -Werror
+MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-y := nic_uio.c
+
+include $(RTE_SDK)/mk/rte.bsdmodule.mk
diff --git a/lib/librte_eal/bsdapp/nic_uio/nic_uio.c b/lib/librte_eal/bsdapp/nic_uio/nic_uio.c
new file mode 100644 (file)
index 0000000..ce97dfc
--- /dev/null
@@ -0,0 +1,325 @@
+/* -
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ *   OWNER 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.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h> /* defines used in kernel.h */
+#include <sys/module.h>
+#include <sys/kernel.h> /* types used in module initialization */
+#include <sys/conf.h> /* cdevsw struct */
+#include <sys/bus.h> /* structs, prototypes for pci bus stuff and DEVMETHOD */
+#include <sys/rman.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <machine/bus.h>
+#include <dev/pci/pcivar.h> /* For pci_get macros! */
+#include <dev/pci/pcireg.h> /* The softc holds our per-instance data. */
+#include <vm/vm.h>
+#include <vm/uma.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+
+#define MAX_BARS (PCIR_MAX_BAR_0 + 1)
+
+
+struct nic_uio_softc {
+       device_t        dev_t;
+       struct cdev     *my_cdev;
+       int              bar_id[MAX_BARS];
+       struct resource *bar_res[MAX_BARS];
+       u_long           bar_start[MAX_BARS];
+       u_long           bar_size[MAX_BARS];
+};
+
+/* Function prototypes */
+static d_open_t         nic_uio_open;
+static d_close_t        nic_uio_close;
+static d_mmap_t         nic_uio_mmap;
+static d_mmap_single_t  nic_uio_mmap_single;
+static int              nic_uio_probe(device_t dev);
+static int              nic_uio_attach(device_t dev);
+static int              nic_uio_detach(device_t dev);
+static int              nic_uio_shutdown(void);
+static int              nic_uio_modevent(module_t mod, int type, void *arg);
+
+static struct cdevsw uio_cdevsw = {
+               .d_name        = "nic_uio",
+               .d_version     = D_VERSION,
+               .d_open        = nic_uio_open,
+               .d_close       = nic_uio_close,
+               .d_mmap        = nic_uio_mmap,
+               .d_mmap_single = nic_uio_mmap_single,
+};
+
+static device_method_t nic_uio_methods[] = {
+       DEVMETHOD(device_probe,    nic_uio_probe),
+       DEVMETHOD(device_attach,   nic_uio_attach),
+       DEVMETHOD(device_detach,   nic_uio_detach),
+       DEVMETHOD_END
+};
+
+struct device {
+    int vend;
+    int dev;
+};
+
+struct pci_bdf {
+       uint32_t bus;
+       uint32_t devid;
+       uint32_t function;
+};
+
+
+#define RTE_PCI_DEV_ID_DECL_EM(vend, dev)      {vend, dev},
+#define RTE_PCI_DEV_ID_DECL_IGB(vend, dev)     {vend, dev},
+#define RTE_PCI_DEV_ID_DECL_IGBVF(vend, dev)   {vend, dev},
+#define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev)   {vend, dev},
+#define RTE_PCI_DEV_ID_DECL_IXGBEVF(vend, dev) {vend, dev},
+#define RTE_PCI_DEV_ID_DECL_VIRTIO(vend, dev)  {vend, dev},
+
+const struct device devices[] = {
+#include <rte_pci_dev_ids.h>
+};
+#define NUM_DEVICES (sizeof(devices)/sizeof(devices[0]))
+
+
+static devclass_t nic_uio_devclass;
+
+DEFINE_CLASS_0(nic_uio, nic_uio_driver, nic_uio_methods, sizeof(struct nic_uio_softc));
+DRIVER_MODULE(nic_uio, pci, nic_uio_driver, nic_uio_devclass, nic_uio_modevent, 0);
+
+static int
+nic_uio_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
+               int prot, vm_memattr_t *memattr)
+{
+       *paddr = offset;
+       return (0);
+}
+
+static int
+nic_uio_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
+               struct vm_object **obj, int nprot)
+{
+       /*
+        * The BAR index is encoded in the offset.  Divide the offset by
+        *  PAGE_SIZE to get the index of the bar requested by the user
+        *  app.
+        */
+       unsigned bar = *offset/PAGE_SIZE;
+       struct nic_uio_softc *sc = cdev->si_drv1;
+
+       if (bar >= MAX_BARS)
+               return EINVAL;
+
+       if (sc->bar_res[bar] == NULL) {
+               sc->bar_id[bar] = PCIR_BAR(bar);
+
+               if (PCI_BAR_IO(pci_read_config(sc->dev_t, sc->bar_id[bar], 4)))
+                       sc->bar_res[bar] = bus_alloc_resource_any(sc->dev_t, SYS_RES_IOPORT,
+                                       &sc->bar_id[bar], RF_ACTIVE);
+               else
+                       sc->bar_res[bar] = bus_alloc_resource_any(sc->dev_t, SYS_RES_MEMORY,
+                                       &sc->bar_id[bar], RF_ACTIVE);
+       }
+       if (sc->bar_res[bar] == NULL)
+               return ENXIO;
+
+       sc->bar_start[bar] = rman_get_start(sc->bar_res[bar]);
+       sc->bar_size[bar] = rman_get_size(sc->bar_res[bar]);
+
+       device_printf(sc->dev_t, "Bar %u @ %lx, size %lx\n", bar,
+                       sc->bar_start[bar], sc->bar_size[bar]);
+
+       *offset = sc->bar_start[bar];
+       *obj = vm_pager_allocate(OBJT_DEVICE, cdev, size, nprot, *offset,
+                               curthread->td_ucred);
+       return 0;
+}
+
+
+int
+nic_uio_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
+{
+       return 0;
+}
+
+int
+nic_uio_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
+{
+       return 0;
+}
+
+static int
+nic_uio_probe (device_t dev)
+{
+       int i;
+
+       for (i = 0; i < NUM_DEVICES; i++)
+               if (pci_get_vendor(dev) == devices[i].vend &&
+                       pci_get_device(dev) == devices[i].dev) {
+
+                       device_set_desc(dev, "Intel(R) DPDK PCI Device");
+                       return (BUS_PROBE_SPECIFIC);
+               }
+
+       return (ENXIO);
+}
+
+static int
+nic_uio_attach(device_t dev)
+{
+       int i;
+       struct nic_uio_softc *sc;
+
+       sc = device_get_softc(dev);
+       sc->dev_t = dev;
+       sc->my_cdev = make_dev(&uio_cdevsw, device_get_unit(dev),
+                       UID_ROOT, GID_WHEEL, 0600, "uio@pci:%u:%u:%u",
+                       pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev));
+       if (sc->my_cdev == NULL)
+               return ENXIO;
+       sc->my_cdev->si_drv1 = sc;
+
+       for (i = 0; i < MAX_BARS; i++)
+               sc->bar_res[i] = NULL;
+
+       pci_enable_busmaster(dev);
+
+       return 0;
+}
+
+static int
+nic_uio_detach(device_t dev)
+{
+       int i;
+       struct nic_uio_softc *sc;
+       sc = device_get_softc(dev);
+
+       for (i = 0; i < MAX_BARS; i++)
+               if (sc->bar_res[i] != NULL) {
+
+                       if (PCI_BAR_IO(pci_read_config(dev, sc->bar_id[i], 4)))
+                               bus_release_resource(dev, SYS_RES_IOPORT, sc->bar_id[i],
+                                               sc->bar_res[i]);
+                       else 
+                               bus_release_resource(dev, SYS_RES_MEMORY, sc->bar_id[i],
+                                               sc->bar_res[i]);
+               }
+
+       if (sc->my_cdev != NULL)
+               destroy_dev(sc->my_cdev);
+       return 0;
+}
+
+static void
+nic_uio_load(void)
+{
+       uint32_t bus, device, function;
+       int i;
+       device_t dev;
+       char bdf_str[256];
+       char *token, *remaining;
+
+       memset(bdf_str, 0, sizeof(bdf_str));
+       TUNABLE_STR_FETCH("hw.nic_uio.bdfs", bdf_str, sizeof(bdf_str));
+       remaining = bdf_str;
+       /*
+        * Users should specify PCI BDFs in the format "b:d:f,b:d:f,b:d:f".
+        *  But the code below does not try differentiate between : and ,
+        *  and just blindly uses 3 tokens at a time to construct a
+        *  bus/device/function tuple.
+        *
+        * There is no checking on strtol() return values, but this should
+        *  be OK.  Worst case is it cannot convert and returns 0.  This
+        *  could give us a different BDF than intended, but as long as the
+        *  PCI device/vendor ID does not match it will not matter.
+        */
+       while (1) {
+               if (remaining == NULL || remaining[0] == '\0')
+                       break;
+               token = strsep(&remaining, ",:");
+               if (token == NULL)
+                       break;
+               bus = strtol(token, NULL, 10);
+               token = strsep(&remaining, ",:");
+               if (token == NULL)
+                       break;
+               device = strtol(token, NULL, 10);
+               token = strsep(&remaining, ",:");
+               if (token == NULL)
+                       break;
+               function = strtol(token, NULL, 10);
+
+               dev = pci_find_bsf(bus, device, function);
+               if (dev != NULL)
+                       for (i = 0; i < NUM_DEVICES; i++) 
+                               if (pci_get_vendor(dev) == devices[i].vend &&
+                                               pci_get_device(dev) == devices[i].dev)
+                                                       device_detach(dev);
+       }
+}
+
+static void
+nic_uio_unload(void)
+{
+}
+
+static int
+nic_uio_shutdown(void)
+{
+       return (0);
+}
+
+static int
+nic_uio_modevent(module_t mod, int type, void *arg)
+{
+
+       switch (type) {
+       case MOD_LOAD:
+               nic_uio_load();
+               break;
+       case MOD_UNLOAD:
+               nic_uio_unload();
+               break;
+       case MOD_SHUTDOWN:
+               nic_uio_shutdown();
+               break;
+       default:
+               break;
+       }
+
+       return (0);
+}
index b238918..0243816 100644 (file)
@@ -53,7 +53,11 @@ rte_strerror(int errnum)
         * themselves if errnum is too big, we handle that case here */
        if (errnum > RTE_MAX_ERRNO)
                rte_snprintf(RTE_PER_LCORE(retval), RETVAL_SZ,
+#ifdef RTE_EXEC_ENV_BSDAPP
+                               "Unknown error: %d", errnum);
+#else
                                "Unknown error %d", errnum);
+#endif
        else
                switch (errnum){
                case E_RTE_SECONDARY:
index 2ab3473..454a785 100644 (file)
@@ -102,66 +102,6 @@ struct log_cur_msg {
 } __rte_cache_aligned;
 static struct log_cur_msg log_cur_msg[RTE_MAX_LCORE]; /**< per core log */
 
-/* early logs */
-
-/*
- * early log function, used during boot when mempool (hence log
- * history) is not available
- */
-static ssize_t
-early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
-{
-       ssize_t ret;
-       ret = fwrite(buf, size, 1, stdout);
-       fflush(stdout);
-       if (ret == 0)
-               return -1;
-       return ret;
-}
-
-static ssize_t
-early_log_read(__attribute__((unused)) void *c,
-              __attribute__((unused)) char *buf,
-              __attribute__((unused)) size_t size)
-{
-       return 0;
-}
-
-/*
- * this is needed because cookies_io_functions_t has a different
- * prototype between newlib and glibc
- */
-#ifdef RTE_EXEC_ENV_LINUXAPP
-static int
-early_log_seek(__attribute__((unused)) void *c,
-              __attribute__((unused)) off64_t *offset,
-              __attribute__((unused)) int whence)
-{
-       return -1;
-}
-#else
-static int
-early_log_seek(__attribute__((unused)) void *c,
-              __attribute__((unused)) _off_t *offset,
-              __attribute__((unused)) int whence)
-{
-       return -1;
-}
-#endif
-
-static int
-early_log_close(__attribute__((unused)) void *c)
-{
-       return 0;
-}
-
-static cookie_io_functions_t early_log_func = {
-       .read  = early_log_read,
-       .write = early_log_write,
-       .seek  = early_log_seek,
-       .close = early_log_close
-};
-static FILE *early_log_stream;
 
 /* default logs */
 
@@ -342,22 +282,6 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
        return ret;
 }
 
-/*
- * init the log library, called by rte_eal_init() to enable early
- * logs
- */
-int
-rte_eal_log_early_init(void)
-{
-       early_log_stream = fopencookie(NULL, "w+", early_log_func);
-       if (early_log_stream == NULL) {
-               printf("Cannot configure early_log_stream\n");
-               return -1;
-       }
-       rte_openlog_stream(early_log_stream);
-       return 0;
-}
-
 /*
  * called by environment-specific log init function to initialize log
  * history
index b44db00..d2c6265 100644 (file)
@@ -54,7 +54,9 @@ enum rte_page_sizes {
 };
 
 #define SOCKET_ID_ANY -1                    /**< Any NUMA socket. */
+#ifndef CACHE_LINE_SIZE
 #define CACHE_LINE_SIZE 64                  /**< Cache line size. */
+#endif
 #define CACHE_LINE_MASK (CACHE_LINE_SIZE-1) /**< Cache line mask. */
 
 #define CACHE_LINE_ROUNDUP(size) \
index e63ff48..753f180 100644 (file)
@@ -133,3 +133,65 @@ rte_eal_log_init(const char *id, int facility)
        return 0;
 }
 
+/* early logs */
+
+/*
+ * early log function, used during boot when mempool (hence log
+ * history) is not available
+ */
+static ssize_t
+early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
+{
+       ssize_t ret;
+       ret = fwrite(buf, size, 1, stdout);
+       fflush(stdout);
+       if (ret == 0)
+               return -1;
+       return ret;
+}
+
+static ssize_t
+early_log_read(__attribute__((unused)) void *c,
+              __attribute__((unused)) char *buf,
+              __attribute__((unused)) size_t size)
+{
+       return 0;
+}
+
+static int
+early_log_seek(__attribute__((unused)) void *c,
+              __attribute__((unused)) off64_t *offset,
+              __attribute__((unused)) int whence)
+{
+       return -1;
+}
+
+static int
+early_log_close(__attribute__((unused)) void *c)
+{
+       return 0;
+}
+
+static cookie_io_functions_t early_log_func = {
+       .read  = early_log_read,
+       .write = early_log_write,
+       .seek  = early_log_seek,
+       .close = early_log_close
+};
+static FILE *early_log_stream;
+
+/*
+ * init the log library, called by rte_eal_init() to enable early
+ * logs
+ */
+int
+rte_eal_log_early_init(void)
+{
+       early_log_stream = fopencookie(NULL, "w+", early_log_func);
+       if (early_log_stream == NULL) {
+               printf("Cannot configure early_log_stream\n");
+               return -1;
+       }
+       rte_openlog_stream(early_log_stream);
+       return 0;
+}
index 0873fdc..2f447e0 100644 (file)
@@ -31,8 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <string.h>
-#include <sys/user.h>
-#include <linux/binfmts.h>
+#include <unistd.h>
 
 #include <rte_malloc.h>
 #include <rte_log.h>
@@ -121,14 +120,14 @@ rte_eth_pcap_tokenize_args(struct args_dict *dict,
                return -1;
        }
 
-       num_of_pairs = rte_strsplit(args, strnlen(args, MAX_ARG_STRLEN), pairs,
+       num_of_pairs = rte_strsplit(args, strnlen(args, sysconf(_SC_ARG_MAX)), pairs,
                        RTE_ETH_PCAP_ARG_PARSER_MAX_ARGS, RTE_ETH_PCAP_PAIRS_DELIM);
 
        for (i = 0; i < num_of_pairs; i++) {
                pair[0] = NULL;
                pair[1] = NULL;
 
-               rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN), pair, 2,
+               rte_strsplit(pairs[i], strnlen(pairs[i], sysconf(_SC_ARG_MAX)), pair, 2,
                                RTE_ETH_PCAP_KEY_VALUE_DELIM);
 
                if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0
index d1da019..f163877 100644 (file)
 #define _VIRTIO_PCI_H_
 
 #include <stdint.h>
+
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#else
 #include <sys/io.h>
+#endif
 
 #include <rte_ethdev.h>
 
@@ -204,6 +210,28 @@ struct virtio_net_config {
 /* The alignment to use between consumer and producer parts of vring. */
 #define VIRTIO_PCI_VRING_ALIGN 4096
 
+#ifdef __FreeBSD__
+
+static inline void
+outb_p(unsigned char data, unsigned int port)
+{
+
+       outb(port, (u_char)data);
+}
+
+static inline void
+outw_p(unsigned short data, unsigned int port)
+{
+       outw(port, (u_short)data);
+}
+
+static inline void
+outl_p(unsigned int data, unsigned int port)
+{
+       outl(port, (u_int)data);
+}
+#endif
+
 #define VIRTIO_PCI_REG_ADDR(hw, reg) \
        (unsigned short)((hw)->io_base + (reg))
 
index 96b6330..796fa35 100644 (file)
@@ -51,7 +51,7 @@ ARCH  ?= x86_64
 CROSS ?=
 
 CPU_CFLAGS  ?= -m64
-CPU_LDFLAGS ?= -melf_x86_64
+CPU_LDFLAGS ?= 
 CPU_ASFLAGS ?= -felf64
 
 export ARCH CROSS CPU_CFLAGS CPU_LDFLAGS CPU_ASFLAGS
diff --git a/mk/exec-env/bsdapp/rte.app.mk b/mk/exec-env/bsdapp/rte.app.mk
new file mode 100644 (file)
index 0000000..1e2297d
--- /dev/null
@@ -0,0 +1,36 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+exec-env-appinstall:
+       @true
+
+exec-env-appclean:
+       @true
diff --git a/mk/exec-env/bsdapp/rte.vars.mk b/mk/exec-env/bsdapp/rte.vars.mk
new file mode 100644 (file)
index 0000000..a3fb71f
--- /dev/null
@@ -0,0 +1,61 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+#
+# exec-env:
+#
+#   - define EXECENV_CFLAGS variable (overriden by cmdline)
+#   - define EXECENV_LDFLAGS variable (overriden by cmdline)
+#   - define EXECENV_ASFLAGS variable (overriden by cmdline)
+#   - may override any previously defined variable
+#
+# examples for RTE_EXEC_ENV: linuxapp, baremetal
+#
+ifeq ($(RTE_BUILD_SHARED_LIB),y)
+EXECENV_CFLAGS  = -pthread -fPIC
+else
+EXECENV_CFLAGS  = -pthread
+endif
+
+EXECENV_LDFLAGS = 
+EXECENV_LDLIBS  = -lexecinfo
+EXECENV_ASFLAGS =
+
+ifeq ($(RTE_BUILD_SHARED_LIB),y)
+EXECENV_LDLIBS += -lgcc_s
+endif
+
+# force applications to link with gcc/icc instead of using ld
+LINK_USING_CC := 1
+
+BSDMAKE=/usr/bin/make
+
+export EXECENV_CFLAGS EXECENV_LDFLAGS EXECENV_ASFLAGS
diff --git a/mk/rte.bsdmodule.mk b/mk/rte.bsdmodule.mk
new file mode 100644 (file)
index 0000000..6224715
--- /dev/null
@@ -0,0 +1,118 @@
+#   BSD LICENSE
+# 
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+# 
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+# 
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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.
+#     * Neither the name of Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+#   OWNER 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.
+
+##### if sourced from kernel Kbuild system
+ifneq ($(KERNELRELEASE),)
+override EXTRA_CFLAGS = $(MODULE_CFLAGS) $(EXTRA_KERNEL_CFLAGS)
+obj-m          += $(MODULE).o
+ifneq ($(MODULE),$(notdir $(SRCS-y:%.c=%)))
+$(MODULE)-objs += $(notdir $(SRCS-y:%.c=%.o))
+endif
+
+##### if launched from rte build system
+else
+
+include $(RTE_SDK)/mk/internal/rte.install-pre.mk
+include $(RTE_SDK)/mk/internal/rte.clean-pre.mk
+include $(RTE_SDK)/mk/internal/rte.build-pre.mk
+include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
+
+# DPDK uses a more up-to-date gcc, so clear the override here.
+unexport CC
+
+# VPATH contains at least SRCDIR
+VPATH += $(SRCDIR)
+
+_BUILD = $(MODULE).ko
+_INSTALL = $(INSTALL-FILES-y) $(SYMLINK-FILES-y) \
+       $(RTE_OUTPUT)/kmod/$(MODULE).ko
+_CLEAN = doclean
+
+SRCS_LINKS = $(addsuffix _link,$(SRCS-y))
+
+compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1)))
+
+.PHONY: all
+all: install
+
+.PHONY: install
+install: build _postinstall
+
+_postinstall: build
+
+.PHONY: build
+build: _postbuild
+
+# Link all sources in build directory
+%_link: FORCE
+       $(if $(call compare,$(notdir $*),$*),\
+       @if [ ! -f $(notdir $(*)) ]; then ln -nfs $(SRCDIR)/$(*) . ; fi,\
+       @if [ ! -f $(notdir $(*)) ]; then ln -nfs $(SRCDIR)/$(*) . ; fi)
+
+# build module
+$(MODULE).ko: $(SRCS_LINKS)
+       @if [ ! -f $(notdir Makefile) ]; then ln -nfs $(SRCDIR)/Makefile . ; fi
+       @if [ ! -f $(notdir BSDmakefile) ]; then ln -nfs $(SRCDIR)/BSDmakefile . ; fi
+       @MAKEFLAGS= $(BSDMAKE) -v 
+
+# install module in $(RTE_OUTPUT)/kmod
+$(RTE_OUTPUT)/kmod/$(MODULE).ko: $(MODULE).ko
+       @echo INSTALL-MODULE $(MODULE).ko
+       @[ -d $(RTE_OUTPUT)/kmod ] || mkdir -p $(RTE_OUTPUT)/kmod
+       @cp -f $(MODULE).ko $(RTE_OUTPUT)/kmod
+
+# install module
+modules_install:
+       @MAKEFLAGS= $(BSDMAKE) install
+
+.PHONY: clean
+clean: _postclean
+
+# do a make clean and remove links
+.PHONY: doclean
+doclean:
+       @if [ ! -f $(notdir Makefile) ]; then ln -nfs $(SRCDIR)/Makefile . ; fi
+       $(Q)$(MAKE) -C $(RTE_KERNELDIR) M=$(CURDIR) O=$(RTE_KERNELDIR) clean
+       @$(foreach FILE,$(SRCS-y) $(SRCS-n) $(SRCS-),\
+               if [ -h $(notdir $(FILE)) ]; then rm -f $(notdir $(FILE)) ; fi ;)
+       @if [ -h $(notdir Makefile) ]; then rm -f $(notdir Makefile) ; fi
+       @rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS) \
+               $(INSTALL-FILES-all)
+
+include $(RTE_SDK)/mk/internal/rte.install-post.mk
+include $(RTE_SDK)/mk/internal/rte.clean-post.mk
+include $(RTE_SDK)/mk/internal/rte.build-post.mk
+include $(RTE_SDK)/mk/internal/rte.depdirs-post.mk
+
+.PHONY: FORCE
+FORCE:
+
+endif
index 16c4101..b188d64 100644 (file)
@@ -68,7 +68,7 @@ clean: $(CLEANDIRS)
        @[ -d $(RTE_OUTPUT)/include ] || mkdir -p $(RTE_OUTPUT)/include
        @$(RTE_SDK)/scripts/gen-config-h.sh $(RTE_OUTPUT)/.config \
                > $(RTE_OUTPUT)/include/rte_config.h
-       $(Q)$(MAKE) -f $(RTE_SDK)/Makefile gcovclean
+       $(Q)$(MAKE) -f $(RTE_SDK)/GNUmakefile gcovclean
        @echo Clean complete
 
 .SECONDEXPANSION: