From: Bruce Richardson Date: Mon, 10 Feb 2014 11:49:10 +0000 (+0000) Subject: add FreeBSD support X-Git-Tag: spdx-start~11053 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=764bf26873b95761ac3bd4b98251d3c497c65a90;p=dpdk.git add FreeBSD support 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 --- diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000000..7afb9ee7e6 --- /dev/null +++ b/GNUmakefile @@ -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 diff --git a/Makefile b/Makefile index 7afb9ee7e6..d789491b48 100644 --- a/Makefile +++ b/Makefile @@ -29,17 +29,5 @@ # (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 diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 062a233e97..4bf0720eb2 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -41,7 +41,11 @@ #include #include #ifndef __linux__ +#ifndef __FreeBSD__ #include +#else +#include +#endif #endif #include diff --git a/app/test/commands.c b/app/test/commands.c index 4770817891..118f70d458 100644 --- a/app/test/commands.c +++ b/app/test/commands.c @@ -39,8 +39,10 @@ #include #include #ifndef __linux__ +#ifndef __FreeBSD__ #include #endif +#endif #include #include #include diff --git a/app/test/process.h b/app/test/process.h index 8894360a24..f896b04f57 100644 --- a/app/test/process.h +++ b/app/test/process.h @@ -36,6 +36,14 @@ #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 */ diff --git a/app/test/test_cmdline_ipaddr.c b/app/test/test_cmdline_ipaddr.c index 4c9eb555fd..c809411a13 100644 --- a/app/test/test_cmdline_ipaddr.c +++ b/app/test/test_cmdline_ipaddr.c @@ -37,7 +37,11 @@ #include #ifndef __linux__ +#ifndef __FreeBSD__ #include +#else +#include +#endif #endif #include @@ -56,13 +60,17 @@ (((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 diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c index 5517f865ee..2d09385384 100644 --- a/app/test/test_eal_flags.c +++ b/app/test/test_eal_flags.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/app/test/test_eal_fs.c b/app/test/test_eal_fs.c index 438d4dcc6a..93d8a7fcfd 100644 --- a/app/test/test_eal_fs.c +++ b/app/test/test_eal_fs.c @@ -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 diff --git a/app/test/test_errno.c b/app/test/test_errno.c index 0af4f78e6c..24065e5b0d 100644 --- a/app/test/test_errno.c +++ b/app/test/test_errno.c @@ -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 */ diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c index 64efb39064..aceb56773e 100644 --- a/app/test/test_mp_secondary.c +++ b/app/test/test_mp_secondary.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include diff --git a/config/defconfig_x86_64-default-bsdapp-gcc b/config/defconfig_x86_64-default-bsdapp-gcc new file mode 100644 index 0000000000..e415825133 --- /dev/null +++ b/config/defconfig_x86_64-default-bsdapp-gcc @@ -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 diff --git a/examples/cmdline/commands.c b/examples/cmdline/commands.c index 60d190994b..afce7159cb 100644 --- a/examples/cmdline/commands.c +++ b/examples/cmdline/commands.c @@ -67,7 +67,11 @@ #include #include #ifndef __linux__ -#include + #ifdef __FreeBSD__ + #include + #else + #include + #endif #endif #include diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile index d763157d62..3c840e115c 100644 --- a/lib/librte_cmdline/Makefile +++ b/lib/librte_cmdline/Makefile @@ -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 diff --git a/lib/librte_cmdline/cmdline_parse_ipaddr.c b/lib/librte_cmdline/cmdline_parse_ipaddr.c index 68f4625b00..2861fc777e 100644 --- a/lib/librte_cmdline/cmdline_parse_ipaddr.c +++ b/lib/librte_cmdline/cmdline_parse_ipaddr.c @@ -87,7 +87,11 @@ #include #include #ifndef __linux__ +#ifndef __FreeBSD__ #include +#else +#include +#endif #endif #include diff --git a/lib/librte_cmdline/cmdline_parse_portlist.c b/lib/librte_cmdline/cmdline_parse_portlist.c index f28b43bbd1..e997f30ca7 100644 --- a/lib/librte_cmdline/cmdline_parse_portlist.c +++ b/lib/librte_cmdline/cmdline_parse_portlist.c @@ -65,10 +65,6 @@ #include #include #include -#include -#ifndef __linux__ -#include -#endif #include #include "cmdline_parse.h" diff --git a/lib/librte_eal/Makefile b/lib/librte_eal/Makefile index 30cbd9b070..586fddcd74 100644 --- a/lib/librte_eal/Makefile +++ b/lib/librte_eal/Makefile @@ -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 index 0000000000..22fc4a3f46 --- /dev/null +++ b/lib/librte_eal/bsdapp/Makefile @@ -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 index 0000000000..9af486d75a --- /dev/null +++ b/lib/librte_eal/bsdapp/contigmem/BSDmakefile @@ -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 diff --git a/lib/librte_eal/bsdapp/contigmem/Makefile b/lib/librte_eal/bsdapp/contigmem/Makefile new file mode 100644 index 0000000000..1818501aa7 --- /dev/null +++ b/lib/librte_eal/bsdapp/contigmem/Makefile @@ -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 index 0000000000..dfe3a903f7 --- /dev/null +++ b/lib/librte_eal/bsdapp/contigmem/contigmem.c @@ -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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +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 index 0000000000..73facaeadc --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/Makefile @@ -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 index 0000000000..be00f9120a --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ]" + "[--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 : 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 index 0000000000..77d30f2818 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_alarm.c @@ -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 +#include + +#include +#include +#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 index 0000000000..7dd3eb9c6b --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_debug.c @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 index 0000000000..dae3c8b2e9 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_hugepage_info.c @@ -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 +#include +#include +#include + +#include +#include +#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 index 0000000000..dafece546a --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_interrupts.c @@ -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 +#include +#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 index 0000000000..e2f3793025 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_lcore.c @@ -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 +#include + +#include +#include +#include +#include +#include + +#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 index 0000000000..55b7376b26 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_log.c @@ -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 +#include +#include + +#include + +/* + * 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 index 0000000000..7d2d269e9a --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_memory.c @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#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 index 0000000000..7b04fa6dfe --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000000..d2bec2e3c9 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_thread.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000000..b6cea1790d --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/eal_timer.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000000..034e58d806 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/eal_filesystem.h @@ -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 +#include +#include +#include + +#include +#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 index 0000000000..064cdb0adc --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/eal_hugepages.h @@ -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 +#include +#include + +#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 index 0000000000..643db7cfcc --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/eal_internal_cfg.h @@ -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 + +#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 index 0000000000..c21b4b05b7 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/eal_thread.h @@ -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 index 0000000000..ea05d58492 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h @@ -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 +#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 index 0000000000..67339488f4 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h @@ -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 " +#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 index 0000000000..ad73febe2f --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_kni_common.h @@ -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 +#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 index 0000000000..57499b72cd --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_lcore.h @@ -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 " +#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 index 0000000000..173c6340f8 --- /dev/null +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_per_lcore.h @@ -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 " +#endif + +#ifndef _RTE_LINUXAPP_PER_LCORE_H_ +#define _RTE_LINUXAPP_PER_LCORE_H_ + +/** + * @file + * Per-lcore variables in RTE on linuxapp environment + */ + +#include + +/** + * 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 index 0000000000..ef3929b80c --- /dev/null +++ b/lib/librte_eal/bsdapp/nic_uio/BSDmakefile @@ -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 diff --git a/lib/librte_eal/bsdapp/nic_uio/Makefile b/lib/librte_eal/bsdapp/nic_uio/Makefile new file mode 100644 index 0000000000..60094dcc1c --- /dev/null +++ b/lib/librte_eal/bsdapp/nic_uio/Makefile @@ -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 index 0000000000..ce97dfcf68 --- /dev/null +++ b/lib/librte_eal/bsdapp/nic_uio/nic_uio.c @@ -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 +__FBSDID("$FreeBSD$"); + +#include /* defines used in kernel.h */ +#include +#include /* types used in module initialization */ +#include /* cdevsw struct */ +#include /* structs, prototypes for pci bus stuff and DEVMETHOD */ +#include +#include +#include + +#include +#include /* For pci_get macros! */ +#include /* The softc holds our per-instance data. */ +#include +#include +#include +#include +#include + + +#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 +}; +#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); +} diff --git a/lib/librte_eal/common/eal_common_errno.c b/lib/librte_eal/common/eal_common_errno.c index b2389187b6..0243816fae 100644 --- a/lib/librte_eal/common/eal_common_errno.c +++ b/lib/librte_eal/common/eal_common_errno.c @@ -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: diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c index 2ab347366e..454a785905 100644 --- a/lib/librte_eal/common/eal_common_log.c +++ b/lib/librte_eal/common/eal_common_log.c @@ -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 diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h index b44db0032a..d2c62658b7 100644 --- a/lib/librte_eal/common/include/rte_memory.h +++ b/lib/librte_eal/common/include/rte_memory.h @@ -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) \ diff --git a/lib/librte_eal/linuxapp/eal/eal_log.c b/lib/librte_eal/linuxapp/eal/eal_log.c index e63ff48231..753f1807e7 100644 --- a/lib/librte_eal/linuxapp/eal/eal_log.c +++ b/lib/librte_eal/linuxapp/eal/eal_log.c @@ -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; +} diff --git a/lib/librte_pmd_pcap/rte_eth_pcap_arg_parser.c b/lib/librte_pmd_pcap/rte_eth_pcap_arg_parser.c index 0873fdca82..2f447e0ca9 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap_arg_parser.c +++ b/lib/librte_pmd_pcap/rte_eth_pcap_arg_parser.c @@ -31,8 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include -#include -#include +#include #include #include @@ -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 diff --git a/lib/librte_pmd_virtio/virtio_pci.h b/lib/librte_pmd_virtio/virtio_pci.h index d1da019de1..f163877f9b 100644 --- a/lib/librte_pmd_virtio/virtio_pci.h +++ b/lib/librte_pmd_virtio/virtio_pci.h @@ -35,7 +35,13 @@ #define _VIRTIO_PCI_H_ #include + +#ifdef __FreeBSD__ +#include +#include +#else #include +#endif #include @@ -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)) diff --git a/mk/arch/x86_64/rte.vars.mk b/mk/arch/x86_64/rte.vars.mk index 96b6330939..796fa3518b 100644 --- a/mk/arch/x86_64/rte.vars.mk +++ b/mk/arch/x86_64/rte.vars.mk @@ -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 index 0000000000..1e2297dc73 --- /dev/null +++ b/mk/exec-env/bsdapp/rte.app.mk @@ -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 index 0000000000..a3fb71f5a9 --- /dev/null +++ b/mk/exec-env/bsdapp/rte.vars.mk @@ -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 index 0000000000..62247154c9 --- /dev/null +++ b/mk/rte.bsdmodule.mk @@ -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 diff --git a/mk/rte.sdkbuild.mk b/mk/rte.sdkbuild.mk index 16c41017a5..b188d64241 100644 --- a/mk/rte.sdkbuild.mk +++ b/mk/rte.sdkbuild.mk @@ -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: