xref: /dpdk/lib/eal/windows/eal.c (revision 2773d39ffee46f66fd628cebdd401d89fce09f1f)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2019 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <stdarg.h>
699a2dd95SBruce Richardson 
799a2dd95SBruce Richardson #include <fcntl.h>
899a2dd95SBruce Richardson #include <io.h>
999a2dd95SBruce Richardson #include <share.h>
1099a2dd95SBruce Richardson #include <sys/stat.h>
1199a2dd95SBruce Richardson 
1299a2dd95SBruce Richardson #include <rte_debug.h>
13770ebc06SDavid Marchand #include <rte_bus.h>
1499a2dd95SBruce Richardson #include <rte_eal.h>
152e2f0272SDavid Marchand #include <rte_eal_memconfig.h>
1699a2dd95SBruce Richardson #include <eal_memcfg.h>
1799a2dd95SBruce Richardson #include <rte_errno.h>
1899a2dd95SBruce Richardson #include <rte_lcore.h>
195bce9bedSMattias Rönnblom #include "eal_lcore_var.h"
2099a2dd95SBruce Richardson #include <eal_thread.h>
2199a2dd95SBruce Richardson #include <eal_internal_cfg.h>
2299a2dd95SBruce Richardson #include <eal_filesystem.h>
2399a2dd95SBruce Richardson #include <eal_options.h>
2499a2dd95SBruce Richardson #include <eal_private.h>
2599a2dd95SBruce Richardson #include <rte_service_component.h>
2699a2dd95SBruce Richardson #include <rte_vfio.h>
2799a2dd95SBruce Richardson 
2840edb9c0SDavid Marchand #include "eal_firmware.h"
2999a2dd95SBruce Richardson #include "eal_hugepages.h"
3099a2dd95SBruce Richardson #include "eal_trace.h"
3199a2dd95SBruce Richardson #include "eal_windows.h"
3209ce4131SBruce Richardson #include "log_internal.h"
3399a2dd95SBruce Richardson 
3499a2dd95SBruce Richardson #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson /* define fd variable here, because file needs to be kept open for the
3799a2dd95SBruce Richardson  * duration of the program, as we hold a write lock on it in the primary proc
3899a2dd95SBruce Richardson  */
3999a2dd95SBruce Richardson static int mem_cfg_fd = -1;
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson /* internal configuration (per-core) */
4299a2dd95SBruce Richardson struct lcore_config lcore_config[RTE_MAX_LCORE];
4399a2dd95SBruce Richardson 
4499a2dd95SBruce Richardson /* Detect if we are a primary or a secondary process */
4599a2dd95SBruce Richardson enum rte_proc_type_t
4699a2dd95SBruce Richardson eal_proc_type_detect(void)
4799a2dd95SBruce Richardson {
4899a2dd95SBruce Richardson 	enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
4999a2dd95SBruce Richardson 	const char *pathname = eal_runtime_config_path();
5099a2dd95SBruce Richardson 	const struct rte_config *config = rte_eal_get_configuration();
5199a2dd95SBruce Richardson 
5299a2dd95SBruce Richardson 	/* if we can open the file but not get a write-lock we are a secondary
5399a2dd95SBruce Richardson 	 * process. NOTE: if we get a file handle back, we keep that open
5499a2dd95SBruce Richardson 	 * and don't close it to prevent a race condition between multiple opens
5599a2dd95SBruce Richardson 	 */
5699a2dd95SBruce Richardson 	errno_t err = _sopen_s(&mem_cfg_fd, pathname,
5799a2dd95SBruce Richardson 		_O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE);
5899a2dd95SBruce Richardson 	if (err == 0) {
5999a2dd95SBruce Richardson 		OVERLAPPED soverlapped = { 0 };
6099a2dd95SBruce Richardson 		soverlapped.Offset = sizeof(*config->mem_config);
6199a2dd95SBruce Richardson 		soverlapped.OffsetHigh = 0;
6299a2dd95SBruce Richardson 
6399a2dd95SBruce Richardson 		HANDLE hwinfilehandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
6499a2dd95SBruce Richardson 
6599a2dd95SBruce Richardson 		if (!LockFileEx(hwinfilehandle,
6699a2dd95SBruce Richardson 			LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
6799a2dd95SBruce Richardson 			sizeof(*config->mem_config), 0, &soverlapped))
6899a2dd95SBruce Richardson 			ptype = RTE_PROC_SECONDARY;
6999a2dd95SBruce Richardson 	}
7099a2dd95SBruce Richardson 
71ae67895bSDavid Marchand 	EAL_LOG(INFO, "Auto-detected process type: %s",
7299a2dd95SBruce Richardson 		ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson 	return ptype;
7599a2dd95SBruce Richardson }
7699a2dd95SBruce Richardson 
7799a2dd95SBruce Richardson bool
7899a2dd95SBruce Richardson rte_mp_disable(void)
7999a2dd95SBruce Richardson {
8099a2dd95SBruce Richardson 	return true;
8199a2dd95SBruce Richardson }
8299a2dd95SBruce Richardson 
8399a2dd95SBruce Richardson /* display usage */
8499a2dd95SBruce Richardson static void
8599a2dd95SBruce Richardson eal_usage(const char *prgname)
8699a2dd95SBruce Richardson {
8799a2dd95SBruce Richardson 	rte_usage_hook_t hook = eal_get_application_usage_hook();
8899a2dd95SBruce Richardson 
8999a2dd95SBruce Richardson 	printf("\nUsage: %s ", prgname);
9099a2dd95SBruce Richardson 	eal_common_usage();
9199a2dd95SBruce Richardson 	/* Allow the application to print its usage message too
9299a2dd95SBruce Richardson 	 * if hook is set
9399a2dd95SBruce Richardson 	 */
9499a2dd95SBruce Richardson 	if (hook) {
9599a2dd95SBruce Richardson 		printf("===== Application Usage =====\n\n");
9699a2dd95SBruce Richardson 		(hook)(prgname);
9799a2dd95SBruce Richardson 	}
9899a2dd95SBruce Richardson }
9999a2dd95SBruce Richardson 
10099a2dd95SBruce Richardson /* Parse the argument given in the command line of the application */
10199a2dd95SBruce Richardson static int
10299a2dd95SBruce Richardson eal_parse_args(int argc, char **argv)
10399a2dd95SBruce Richardson {
10499a2dd95SBruce Richardson 	int opt, ret;
10599a2dd95SBruce Richardson 	char **argvopt;
10699a2dd95SBruce Richardson 	int option_index;
10799a2dd95SBruce Richardson 	char *prgname = argv[0];
10899a2dd95SBruce Richardson 	struct internal_config *internal_conf =
10999a2dd95SBruce Richardson 		eal_get_internal_configuration();
11099a2dd95SBruce Richardson 
11199a2dd95SBruce Richardson 	argvopt = argv;
11299a2dd95SBruce Richardson 
11399a2dd95SBruce Richardson 	while ((opt = getopt_long(argc, argvopt, eal_short_options,
11499a2dd95SBruce Richardson 		eal_long_options, &option_index)) != EOF) {
11599a2dd95SBruce Richardson 
11699a2dd95SBruce Richardson 		int ret;
11799a2dd95SBruce Richardson 
11899a2dd95SBruce Richardson 		/* getopt is not happy, stop right now */
11999a2dd95SBruce Richardson 		if (opt == '?') {
12099a2dd95SBruce Richardson 			eal_usage(prgname);
12199a2dd95SBruce Richardson 			return -1;
12299a2dd95SBruce Richardson 		}
12399a2dd95SBruce Richardson 
1249a4276f9SDavid Marchand 		/* eal_parse_log_options() already handled this option */
1259a4276f9SDavid Marchand 		if (eal_option_is_log(opt))
12699a2dd95SBruce Richardson 			continue;
12799a2dd95SBruce Richardson 
12899a2dd95SBruce Richardson 		ret = eal_parse_common_option(opt, optarg, internal_conf);
12999a2dd95SBruce Richardson 		/* common parser is not happy */
13099a2dd95SBruce Richardson 		if (ret < 0) {
13199a2dd95SBruce Richardson 			eal_usage(prgname);
13299a2dd95SBruce Richardson 			return -1;
13399a2dd95SBruce Richardson 		}
13499a2dd95SBruce Richardson 		/* common parser handled this option */
13599a2dd95SBruce Richardson 		if (ret == 0)
13699a2dd95SBruce Richardson 			continue;
13799a2dd95SBruce Richardson 
13899a2dd95SBruce Richardson 		switch (opt) {
139df60837cSThomas Monjalon 		case OPT_HELP_NUM:
14099a2dd95SBruce Richardson 			eal_usage(prgname);
14199a2dd95SBruce Richardson 			exit(EXIT_SUCCESS);
14299a2dd95SBruce Richardson 		default:
14399a2dd95SBruce Richardson 			if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
144ae67895bSDavid Marchand 				EAL_LOG(ERR, "Option %c is not supported "
145ae67895bSDavid Marchand 					"on Windows", opt);
14699a2dd95SBruce Richardson 			} else if (opt >= OPT_LONG_MIN_NUM &&
14799a2dd95SBruce Richardson 				opt < OPT_LONG_MAX_NUM) {
148ae67895bSDavid Marchand 				EAL_LOG(ERR, "Option %s is not supported "
149ae67895bSDavid Marchand 					"on Windows",
15099a2dd95SBruce Richardson 					eal_long_options[option_index].name);
15199a2dd95SBruce Richardson 			} else {
152ae67895bSDavid Marchand 				EAL_LOG(ERR, "Option %d is not supported "
153ae67895bSDavid Marchand 					"on Windows", opt);
15499a2dd95SBruce Richardson 			}
15599a2dd95SBruce Richardson 			eal_usage(prgname);
15699a2dd95SBruce Richardson 			return -1;
15799a2dd95SBruce Richardson 		}
15899a2dd95SBruce Richardson 	}
15999a2dd95SBruce Richardson 
16099a2dd95SBruce Richardson 	if (eal_adjust_config(internal_conf) != 0)
16199a2dd95SBruce Richardson 		return -1;
16299a2dd95SBruce Richardson 
16399a2dd95SBruce Richardson 	/* sanity checks */
16499a2dd95SBruce Richardson 	if (eal_check_common_options(internal_conf) != 0) {
16599a2dd95SBruce Richardson 		eal_usage(prgname);
16699a2dd95SBruce Richardson 		return -1;
16799a2dd95SBruce Richardson 	}
16899a2dd95SBruce Richardson 
16999a2dd95SBruce Richardson 	if (optind >= 0)
17099a2dd95SBruce Richardson 		argv[optind - 1] = prgname;
17199a2dd95SBruce Richardson 	ret = optind - 1;
17299a2dd95SBruce Richardson 	optind = 0; /* reset getopt lib */
17399a2dd95SBruce Richardson 	return ret;
17499a2dd95SBruce Richardson }
17599a2dd95SBruce Richardson 
17699a2dd95SBruce Richardson static int
17799a2dd95SBruce Richardson sync_func(void *arg __rte_unused)
17899a2dd95SBruce Richardson {
17999a2dd95SBruce Richardson 	return 0;
18099a2dd95SBruce Richardson }
18199a2dd95SBruce Richardson 
18299a2dd95SBruce Richardson static void
18399a2dd95SBruce Richardson rte_eal_init_alert(const char *msg)
18499a2dd95SBruce Richardson {
18572bf6da8SStephen Hemminger 	EAL_LOG(ALERT, "%s", msg);
18699a2dd95SBruce Richardson }
18799a2dd95SBruce Richardson 
18899a2dd95SBruce Richardson /* Stubs to enable EAL trace point compilation
18999a2dd95SBruce Richardson  * until eal_common_trace.c can be compiled.
19099a2dd95SBruce Richardson  */
19199a2dd95SBruce Richardson 
19299a2dd95SBruce Richardson RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz);
19399a2dd95SBruce Richardson RTE_DEFINE_PER_LCORE(void *, trace_mem);
19499a2dd95SBruce Richardson 
19599a2dd95SBruce Richardson void
19699a2dd95SBruce Richardson __rte_trace_mem_per_thread_alloc(void)
19799a2dd95SBruce Richardson {
19899a2dd95SBruce Richardson }
19999a2dd95SBruce Richardson 
20099a2dd95SBruce Richardson void
20199a2dd95SBruce Richardson trace_mem_per_thread_free(void)
20299a2dd95SBruce Richardson {
20399a2dd95SBruce Richardson }
20499a2dd95SBruce Richardson 
20599a2dd95SBruce Richardson void
20699a2dd95SBruce Richardson __rte_trace_point_emit_field(size_t sz, const char *field,
20799a2dd95SBruce Richardson 	const char *type)
20899a2dd95SBruce Richardson {
20999a2dd95SBruce Richardson 	RTE_SET_USED(sz);
21099a2dd95SBruce Richardson 	RTE_SET_USED(field);
21199a2dd95SBruce Richardson 	RTE_SET_USED(type);
21299a2dd95SBruce Richardson }
21399a2dd95SBruce Richardson 
21499a2dd95SBruce Richardson int
21599a2dd95SBruce Richardson __rte_trace_point_register(rte_trace_point_t *trace, const char *name,
21699a2dd95SBruce Richardson 	void (*register_fn)(void))
21799a2dd95SBruce Richardson {
21899a2dd95SBruce Richardson 	RTE_SET_USED(trace);
21999a2dd95SBruce Richardson 	RTE_SET_USED(name);
22099a2dd95SBruce Richardson 	RTE_SET_USED(register_fn);
22199a2dd95SBruce Richardson 	return -ENOTSUP;
22299a2dd95SBruce Richardson }
22399a2dd95SBruce Richardson 
22499a2dd95SBruce Richardson int
22599a2dd95SBruce Richardson rte_eal_cleanup(void)
22699a2dd95SBruce Richardson {
22799a2dd95SBruce Richardson 	struct internal_config *internal_conf =
22899a2dd95SBruce Richardson 		eal_get_internal_configuration();
229cfdaa678SDmitry Kozlyuk 
230cfdaa678SDmitry Kozlyuk 	eal_intr_thread_cancel();
23123ce9e0aSDmitry Kozlyuk 	eal_mem_virt2iova_cleanup();
2321cab1a40SKevin Laatz 	eal_bus_cleanup();
23399a2dd95SBruce Richardson 	/* after this point, any DPDK pointers will become dangling */
23499a2dd95SBruce Richardson 	rte_eal_memory_detach();
23599a2dd95SBruce Richardson 	eal_cleanup_config(internal_conf);
2365bce9bedSMattias Rönnblom 	eal_lcore_var_cleanup();
23799a2dd95SBruce Richardson 	return 0;
23899a2dd95SBruce Richardson }
23999a2dd95SBruce Richardson 
24099a2dd95SBruce Richardson /* Launch threads, called at application init(). */
24199a2dd95SBruce Richardson int
24299a2dd95SBruce Richardson rte_eal_init(int argc, char **argv)
24399a2dd95SBruce Richardson {
24499a2dd95SBruce Richardson 	int i, fctret, bscan;
24599a2dd95SBruce Richardson 	const struct rte_config *config = rte_eal_get_configuration();
24699a2dd95SBruce Richardson 	struct internal_config *internal_conf =
24799a2dd95SBruce Richardson 		eal_get_internal_configuration();
2480c8fc83aSDmitry Kozlyuk 	bool has_phys_addr;
2490c8fc83aSDmitry Kozlyuk 	enum rte_iova_mode iova_mode;
25099a2dd95SBruce Richardson 	int ret;
2518001c0ddSTyler Retzlaff 	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
25293d8a7edSThomas Monjalon 	char thread_name[RTE_THREAD_NAME_SIZE];
25399a2dd95SBruce Richardson 
254*2773d39fSStephen Hemminger 	/* setup log as early as possible */
255*2773d39fSStephen Hemminger 	if (eal_parse_log_options(argc, argv) < 0) {
256*2773d39fSStephen Hemminger 		rte_eal_init_alert("invalid log arguments.");
257*2773d39fSStephen Hemminger 		rte_errno = EINVAL;
258*2773d39fSStephen Hemminger 		return -1;
259*2773d39fSStephen Hemminger 	}
26099a2dd95SBruce Richardson 
261*2773d39fSStephen Hemminger 	eal_log_init(NULL);
26299a2dd95SBruce Richardson 
26399a2dd95SBruce Richardson 	if (eal_create_cpu_map() < 0) {
26499a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot discover CPU and NUMA.");
26599a2dd95SBruce Richardson 		/* rte_errno is set */
26699a2dd95SBruce Richardson 		return -1;
26799a2dd95SBruce Richardson 	}
26899a2dd95SBruce Richardson 
269e168b189SDavid Christensen 	/* verify if DPDK supported on architecture MMU */
270e168b189SDavid Christensen 	if (!eal_mmu_supported()) {
271e168b189SDavid Christensen 		rte_eal_init_alert("Unsupported MMU type.");
272e168b189SDavid Christensen 		rte_errno = ENOTSUP;
273e168b189SDavid Christensen 		return -1;
274e168b189SDavid Christensen 	}
275e168b189SDavid Christensen 
27699a2dd95SBruce Richardson 	if (rte_eal_cpu_init() < 0) {
27799a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot detect lcores.");
27899a2dd95SBruce Richardson 		rte_errno = ENOTSUP;
27999a2dd95SBruce Richardson 		return -1;
28099a2dd95SBruce Richardson 	}
28199a2dd95SBruce Richardson 
28299a2dd95SBruce Richardson 	fctret = eal_parse_args(argc, argv);
28399a2dd95SBruce Richardson 	if (fctret < 0)
28499a2dd95SBruce Richardson 		exit(1);
28599a2dd95SBruce Richardson 
28699a2dd95SBruce Richardson 	if (eal_option_device_parse()) {
28799a2dd95SBruce Richardson 		rte_errno = ENODEV;
28899a2dd95SBruce Richardson 		return -1;
28999a2dd95SBruce Richardson 	}
29099a2dd95SBruce Richardson 
29199a2dd95SBruce Richardson 	/* Prevent creation of shared memory files. */
29299a2dd95SBruce Richardson 	if (internal_conf->in_memory == 0) {
293ae67895bSDavid Marchand 		EAL_LOG(WARNING, "Multi-process support is requested, "
294ae67895bSDavid Marchand 			"but not available.");
29599a2dd95SBruce Richardson 		internal_conf->in_memory = 1;
29699a2dd95SBruce Richardson 		internal_conf->no_shconf = 1;
29799a2dd95SBruce Richardson 	}
29899a2dd95SBruce Richardson 
29999a2dd95SBruce Richardson 	if (!internal_conf->no_hugetlbfs && (eal_hugepage_info_init() < 0)) {
30099a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot get hugepage information");
30199a2dd95SBruce Richardson 		rte_errno = EACCES;
30299a2dd95SBruce Richardson 		return -1;
30399a2dd95SBruce Richardson 	}
30499a2dd95SBruce Richardson 
30599a2dd95SBruce Richardson 	if (internal_conf->memory == 0 && !internal_conf->force_sockets) {
30699a2dd95SBruce Richardson 		if (internal_conf->no_hugetlbfs)
30799a2dd95SBruce Richardson 			internal_conf->memory = MEMSIZE_IF_NO_HUGE_PAGE;
30899a2dd95SBruce Richardson 	}
30999a2dd95SBruce Richardson 
3100c8fc83aSDmitry Kozlyuk 	if (rte_eal_intr_init() < 0) {
3110c8fc83aSDmitry Kozlyuk 		rte_eal_init_alert("Cannot init interrupt-handling thread");
3120c8fc83aSDmitry Kozlyuk 		return -1;
3130c8fc83aSDmitry Kozlyuk 	}
3140c8fc83aSDmitry Kozlyuk 
3150c8fc83aSDmitry Kozlyuk 	if (rte_eal_timer_init() < 0) {
3160c8fc83aSDmitry Kozlyuk 		rte_eal_init_alert("Cannot init TSC timer");
3170c8fc83aSDmitry Kozlyuk 		rte_errno = EFAULT;
3180c8fc83aSDmitry Kozlyuk 		return -1;
3190c8fc83aSDmitry Kozlyuk 	}
3200c8fc83aSDmitry Kozlyuk 
3210c8fc83aSDmitry Kozlyuk 	bscan = rte_bus_scan();
3220c8fc83aSDmitry Kozlyuk 	if (bscan < 0) {
3230c8fc83aSDmitry Kozlyuk 		rte_eal_init_alert("Cannot scan the buses");
3240c8fc83aSDmitry Kozlyuk 		rte_errno = ENODEV;
3250c8fc83aSDmitry Kozlyuk 		return -1;
3260c8fc83aSDmitry Kozlyuk 	}
3270c8fc83aSDmitry Kozlyuk 
32899a2dd95SBruce Richardson 	if (eal_mem_win32api_init() < 0) {
32999a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot access Win32 memory management");
33099a2dd95SBruce Richardson 		rte_errno = ENOTSUP;
33199a2dd95SBruce Richardson 		return -1;
33299a2dd95SBruce Richardson 	}
33399a2dd95SBruce Richardson 
3340c8fc83aSDmitry Kozlyuk 	has_phys_addr = true;
33599a2dd95SBruce Richardson 	if (eal_mem_virt2iova_init() < 0) {
33699a2dd95SBruce Richardson 		/* Non-fatal error if physical addresses are not required. */
337ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "Cannot access virt2phys driver, "
338ae67895bSDavid Marchand 			"PA will not be available");
3390c8fc83aSDmitry Kozlyuk 		has_phys_addr = false;
34099a2dd95SBruce Richardson 	}
34199a2dd95SBruce Richardson 
3420c8fc83aSDmitry Kozlyuk 	iova_mode = internal_conf->iova_mode;
3430c8fc83aSDmitry Kozlyuk 	if (iova_mode == RTE_IOVA_DC) {
344ae67895bSDavid Marchand 		EAL_LOG(DEBUG, "Specific IOVA mode is not requested, autodetecting");
3450c8fc83aSDmitry Kozlyuk 		if (has_phys_addr) {
346ae67895bSDavid Marchand 			EAL_LOG(DEBUG, "Selecting IOVA mode according to bus requests");
3470c8fc83aSDmitry Kozlyuk 			iova_mode = rte_bus_get_iommu_class();
348a37335bcSViacheslav Ovsiienko 			if (iova_mode == RTE_IOVA_DC) {
349a37335bcSViacheslav Ovsiienko 				if (!RTE_IOVA_IN_MBUF) {
350a37335bcSViacheslav Ovsiienko 					iova_mode = RTE_IOVA_VA;
351ae67895bSDavid Marchand 					EAL_LOG(DEBUG, "IOVA as VA mode is forced by build option.");
352a37335bcSViacheslav Ovsiienko 				} else	{
3530c8fc83aSDmitry Kozlyuk 					iova_mode = RTE_IOVA_PA;
354a37335bcSViacheslav Ovsiienko 				}
355a37335bcSViacheslav Ovsiienko 			}
3560c8fc83aSDmitry Kozlyuk 		} else {
3570c8fc83aSDmitry Kozlyuk 			iova_mode = RTE_IOVA_VA;
3580c8fc83aSDmitry Kozlyuk 		}
3590c8fc83aSDmitry Kozlyuk 	}
360a37335bcSViacheslav Ovsiienko 
361a37335bcSViacheslav Ovsiienko 	if (iova_mode == RTE_IOVA_PA && !has_phys_addr) {
362a37335bcSViacheslav Ovsiienko 		rte_eal_init_alert("Cannot use IOVA as 'PA' since physical addresses are not available");
363a37335bcSViacheslav Ovsiienko 		rte_errno = EINVAL;
364a37335bcSViacheslav Ovsiienko 		return -1;
365a37335bcSViacheslav Ovsiienko 	}
366a37335bcSViacheslav Ovsiienko 
367a37335bcSViacheslav Ovsiienko 	if (iova_mode == RTE_IOVA_PA && !RTE_IOVA_IN_MBUF) {
368a37335bcSViacheslav Ovsiienko 		rte_eal_init_alert("Cannot use IOVA as 'PA' as it is disabled during build");
369a37335bcSViacheslav Ovsiienko 		rte_errno = EINVAL;
370a37335bcSViacheslav Ovsiienko 		return -1;
371a37335bcSViacheslav Ovsiienko 	}
372a37335bcSViacheslav Ovsiienko 
373ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Selected IOVA mode '%s'",
3740c8fc83aSDmitry Kozlyuk 		iova_mode == RTE_IOVA_PA ? "PA" : "VA");
3750c8fc83aSDmitry Kozlyuk 	rte_eal_get_configuration()->iova_mode = iova_mode;
3760c8fc83aSDmitry Kozlyuk 
37799a2dd95SBruce Richardson 	if (rte_eal_memzone_init() < 0) {
37899a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot init memzone");
37999a2dd95SBruce Richardson 		rte_errno = ENODEV;
38099a2dd95SBruce Richardson 		return -1;
38199a2dd95SBruce Richardson 	}
38299a2dd95SBruce Richardson 
3832e2f0272SDavid Marchand 	rte_mcfg_mem_read_lock();
3842e2f0272SDavid Marchand 
38599a2dd95SBruce Richardson 	if (rte_eal_memory_init() < 0) {
3862e2f0272SDavid Marchand 		rte_mcfg_mem_read_unlock();
38799a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot init memory");
38899a2dd95SBruce Richardson 		rte_errno = ENOMEM;
38999a2dd95SBruce Richardson 		return -1;
39099a2dd95SBruce Richardson 	}
39199a2dd95SBruce Richardson 
39299a2dd95SBruce Richardson 	if (rte_eal_malloc_heap_init() < 0) {
3932e2f0272SDavid Marchand 		rte_mcfg_mem_read_unlock();
3942e2f0272SDavid Marchand 		rte_eal_init_alert("Cannot init malloc heap");
3952e2f0272SDavid Marchand 		rte_errno = ENODEV;
3962e2f0272SDavid Marchand 		return -1;
3972e2f0272SDavid Marchand 	}
3982e2f0272SDavid Marchand 
3992e2f0272SDavid Marchand 	rte_mcfg_mem_read_unlock();
4002e2f0272SDavid Marchand 
4012e2f0272SDavid Marchand 	if (rte_eal_malloc_heap_populate() < 0) {
40299a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot init malloc heap");
40399a2dd95SBruce Richardson 		rte_errno = ENODEV;
40499a2dd95SBruce Richardson 		return -1;
40599a2dd95SBruce Richardson 	}
40699a2dd95SBruce Richardson 
40799a2dd95SBruce Richardson 	if (rte_eal_tailqs_init() < 0) {
40899a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot init tail queues for objects");
40999a2dd95SBruce Richardson 		rte_errno = EFAULT;
41099a2dd95SBruce Richardson 		return -1;
41199a2dd95SBruce Richardson 	}
41299a2dd95SBruce Richardson 
4138b0a1b8cSTyler Retzlaff 	if (rte_thread_set_affinity_by_id(rte_thread_self(),
4148001c0ddSTyler Retzlaff 			&lcore_config[config->main_lcore].cpuset) != 0) {
4158001c0ddSTyler Retzlaff 		rte_eal_init_alert("Cannot set affinity");
4168001c0ddSTyler Retzlaff 		rte_errno = EINVAL;
4178001c0ddSTyler Retzlaff 		return -1;
4188001c0ddSTyler Retzlaff 	}
41999a2dd95SBruce Richardson 	__rte_thread_init(config->main_lcore,
42099a2dd95SBruce Richardson 		&lcore_config[config->main_lcore].cpuset);
42199a2dd95SBruce Richardson 
4228001c0ddSTyler Retzlaff 	ret = eal_thread_dump_current_affinity(cpuset, sizeof(cpuset));
423ae67895bSDavid Marchand 	EAL_LOG(DEBUG, "Main lcore %u is ready (tid=%zx;cpuset=[%s%s])",
424db77fe7dSTyler Retzlaff 		config->main_lcore, rte_thread_self().opaque_id, cpuset,
4258001c0ddSTyler Retzlaff 		ret == 0 ? "" : "...");
4268001c0ddSTyler Retzlaff 
42799a2dd95SBruce Richardson 	RTE_LCORE_FOREACH_WORKER(i) {
42899a2dd95SBruce Richardson 
42999a2dd95SBruce Richardson 		/*
43099a2dd95SBruce Richardson 		 * create communication pipes between main thread
43199a2dd95SBruce Richardson 		 * and children
43299a2dd95SBruce Richardson 		 */
43399a2dd95SBruce Richardson 		if (_pipe(lcore_config[i].pipe_main2worker,
43499a2dd95SBruce Richardson 			sizeof(char), _O_BINARY) < 0)
43599a2dd95SBruce Richardson 			rte_panic("Cannot create pipe\n");
43699a2dd95SBruce Richardson 		if (_pipe(lcore_config[i].pipe_worker2main,
43799a2dd95SBruce Richardson 			sizeof(char), _O_BINARY) < 0)
43899a2dd95SBruce Richardson 			rte_panic("Cannot create pipe\n");
43999a2dd95SBruce Richardson 
44099a2dd95SBruce Richardson 		lcore_config[i].state = WAIT;
44199a2dd95SBruce Richardson 
44299a2dd95SBruce Richardson 		/* create a thread for each lcore */
4438b0a1b8cSTyler Retzlaff 		if (rte_thread_create(&lcore_config[i].thread_id, NULL,
4448b0a1b8cSTyler Retzlaff 				eal_thread_loop, (void *)(uintptr_t)i) != 0)
44599a2dd95SBruce Richardson 			rte_panic("Cannot create thread\n");
446c1c8db59STyler Retzlaff 
447c1c8db59STyler Retzlaff 		/* Set thread name for aid in debugging. */
448c1c8db59STyler Retzlaff 		snprintf(thread_name, sizeof(thread_name),
44962774b78SThomas Monjalon 			"dpdk-worker%d", i);
450c1c8db59STyler Retzlaff 		rte_thread_set_name(lcore_config[i].thread_id, thread_name);
451c1c8db59STyler Retzlaff 
4528b0a1b8cSTyler Retzlaff 		ret = rte_thread_set_affinity_by_id(lcore_config[i].thread_id,
4538b0a1b8cSTyler Retzlaff 			&lcore_config[i].cpuset);
454416c1befSPallavi Kadam 		if (ret != 0)
455ae67895bSDavid Marchand 			EAL_LOG(DEBUG, "Cannot set affinity");
45699a2dd95SBruce Richardson 	}
45799a2dd95SBruce Richardson 
45899a2dd95SBruce Richardson 	/* Initialize services so drivers can register services during probe. */
45999a2dd95SBruce Richardson 	ret = rte_service_init();
46099a2dd95SBruce Richardson 	if (ret) {
46199a2dd95SBruce Richardson 		rte_eal_init_alert("rte_service_init() failed");
46299a2dd95SBruce Richardson 		rte_errno = -ret;
46399a2dd95SBruce Richardson 		return -1;
46499a2dd95SBruce Richardson 	}
46599a2dd95SBruce Richardson 
46699a2dd95SBruce Richardson 	if (rte_bus_probe()) {
46799a2dd95SBruce Richardson 		rte_eal_init_alert("Cannot probe devices");
46899a2dd95SBruce Richardson 		rte_errno = ENOTSUP;
46999a2dd95SBruce Richardson 		return -1;
47099a2dd95SBruce Richardson 	}
47199a2dd95SBruce Richardson 
47299a2dd95SBruce Richardson 	/*
47399a2dd95SBruce Richardson 	 * Launch a dummy function on all worker lcores, so that main lcore
47499a2dd95SBruce Richardson 	 * knows they are all ready when this function returns.
47599a2dd95SBruce Richardson 	 */
47699a2dd95SBruce Richardson 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MAIN);
47799a2dd95SBruce Richardson 	rte_eal_mp_wait_lcore();
47840032e5eSTyler Retzlaff 
47940032e5eSTyler Retzlaff 	eal_mcfg_complete();
48040032e5eSTyler Retzlaff 
48199a2dd95SBruce Richardson 	return fctret;
48299a2dd95SBruce Richardson }
48399a2dd95SBruce Richardson 
48499a2dd95SBruce Richardson /* Don't use MinGW asprintf() to have identical code with all toolchains. */
48599a2dd95SBruce Richardson int
48699a2dd95SBruce Richardson eal_asprintf(char **buffer, const char *format, ...)
48799a2dd95SBruce Richardson {
48899a2dd95SBruce Richardson 	int size, ret;
48999a2dd95SBruce Richardson 	va_list arg;
49099a2dd95SBruce Richardson 
49199a2dd95SBruce Richardson 	va_start(arg, format);
49299a2dd95SBruce Richardson 	size = vsnprintf(NULL, 0, format, arg);
49399a2dd95SBruce Richardson 	va_end(arg);
49499a2dd95SBruce Richardson 	if (size < 0)
49599a2dd95SBruce Richardson 		return -1;
49699a2dd95SBruce Richardson 	size++;
49799a2dd95SBruce Richardson 
49899a2dd95SBruce Richardson 	*buffer = malloc(size);
49999a2dd95SBruce Richardson 	if (*buffer == NULL)
50099a2dd95SBruce Richardson 		return -1;
50199a2dd95SBruce Richardson 
50299a2dd95SBruce Richardson 	va_start(arg, format);
50399a2dd95SBruce Richardson 	ret = vsnprintf(*buffer, size, format, arg);
50499a2dd95SBruce Richardson 	va_end(arg);
50599a2dd95SBruce Richardson 	if (ret != size - 1) {
50699a2dd95SBruce Richardson 		free(*buffer);
50799a2dd95SBruce Richardson 		return -1;
50899a2dd95SBruce Richardson 	}
50999a2dd95SBruce Richardson 	return ret;
51099a2dd95SBruce Richardson }
51199a2dd95SBruce Richardson 
51299a2dd95SBruce Richardson int
51399a2dd95SBruce Richardson rte_vfio_container_dma_map(__rte_unused int container_fd,
51499a2dd95SBruce Richardson 			__rte_unused uint64_t vaddr,
51599a2dd95SBruce Richardson 			__rte_unused uint64_t iova,
51699a2dd95SBruce Richardson 			__rte_unused uint64_t len)
51799a2dd95SBruce Richardson {
5184fd15c6aSAnatoly Burakov 	rte_errno = ENOTSUP;
51999a2dd95SBruce Richardson 	return -1;
52099a2dd95SBruce Richardson }
52199a2dd95SBruce Richardson 
52299a2dd95SBruce Richardson int
52399a2dd95SBruce Richardson rte_vfio_container_dma_unmap(__rte_unused int container_fd,
52499a2dd95SBruce Richardson 			__rte_unused uint64_t vaddr,
52599a2dd95SBruce Richardson 			__rte_unused uint64_t iova,
52699a2dd95SBruce Richardson 			__rte_unused uint64_t len)
52799a2dd95SBruce Richardson {
5284fd15c6aSAnatoly Burakov 	rte_errno = ENOTSUP;
52999a2dd95SBruce Richardson 	return -1;
53099a2dd95SBruce Richardson }
53140edb9c0SDavid Marchand 
53240edb9c0SDavid Marchand int
53340edb9c0SDavid Marchand rte_firmware_read(__rte_unused const char *name,
53440edb9c0SDavid Marchand 			__rte_unused void **buf,
53540edb9c0SDavid Marchand 			__rte_unused size_t *bufsz)
53640edb9c0SDavid Marchand {
53740edb9c0SDavid Marchand 	return -1;
53840edb9c0SDavid Marchand }
539