From cb84d1cf5aa577f71faab4c1e494c3cc580ce1cf Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 12 Mar 2025 18:50:04 +0800
Subject: [PATCH] add sw_64 support

---
 app/test/test_xmmt_ops.h                     |  16 +++
 config/meson.build                           |   2 +
 config/sw_64/meson.build                     |  12 ++
 drivers/net/i40e/i40e_rxtx.c                 |  52 ++++++++
 drivers/net/ixgbe/ixgbe_rxtx.c               |   2 +-
 drivers/net/memif/rte_eth_memif.h            |   2 +
 drivers/net/tap/tap_bpf.h                    |   2 +
 examples/l3fwd/l3fwd_em.c                    |   8 ++
 lib/eal/sw_64/include/meson.build            |  22 ++++
 lib/eal/sw_64/include/rte_altivec.h          |  22 ++++
 lib/eal/sw_64/include/rte_atomic.h           |  48 +++++++
 lib/eal/sw_64/include/rte_byteorder.h        |  57 +++++++++
 lib/eal/sw_64/include/rte_cpuflags.h         |  20 +++
 lib/eal/sw_64/include/rte_cycles.h           |  35 ++++++
 lib/eal/sw_64/include/rte_io.h               |  14 +++
 lib/eal/sw_64/include/rte_mcslock.h          |  18 +++
 lib/eal/sw_64/include/rte_memcpy.h           |  60 +++++++++
 lib/eal/sw_64/include/rte_pause.h            |  20 +++
 lib/eal/sw_64/include/rte_pflock.h           |  18 +++
 lib/eal/sw_64/include/rte_power_intrinsics.h |  20 +++
 lib/eal/sw_64/include/rte_prefetch.h         |  47 +++++++
 lib/eal/sw_64/include/rte_rwlock.h           |  38 ++++++
 lib/eal/sw_64/include/rte_spinlock.h         |  57 +++++++++
 lib/eal/sw_64/include/rte_ticketlock.h       |  18 +++
 lib/eal/sw_64/include/rte_vect.h             |  55 ++++++++
 lib/eal/sw_64/meson.build                    |  11 ++
 lib/eal/sw_64/rte_cpuflags.c                 |  18 +++
 lib/eal/sw_64/rte_cycles.c                   |   7 ++
 lib/eal/sw_64/rte_hypervisor.c               |  11 ++
 lib/eal/sw_64/rte_power_intrinsics.c         |  53 ++++++++
 lib/lpm/rte_lpm.h                            |   2 +
 lib/lpm/rte_lpm_sw.h                         | 124 +++++++++++++++++++
 meson.build                                  |   2 +
 33 files changed, 892 insertions(+), 1 deletion(-)
 create mode 100644 config/sw_64/meson.build
 create mode 100644 lib/eal/sw_64/include/meson.build
 create mode 100644 lib/eal/sw_64/include/rte_altivec.h
 create mode 100644 lib/eal/sw_64/include/rte_atomic.h
 create mode 100644 lib/eal/sw_64/include/rte_byteorder.h
 create mode 100644 lib/eal/sw_64/include/rte_cpuflags.h
 create mode 100644 lib/eal/sw_64/include/rte_cycles.h
 create mode 100644 lib/eal/sw_64/include/rte_io.h
 create mode 100644 lib/eal/sw_64/include/rte_mcslock.h
 create mode 100644 lib/eal/sw_64/include/rte_memcpy.h
 create mode 100644 lib/eal/sw_64/include/rte_pause.h
 create mode 100644 lib/eal/sw_64/include/rte_pflock.h
 create mode 100644 lib/eal/sw_64/include/rte_power_intrinsics.h
 create mode 100644 lib/eal/sw_64/include/rte_prefetch.h
 create mode 100644 lib/eal/sw_64/include/rte_rwlock.h
 create mode 100644 lib/eal/sw_64/include/rte_spinlock.h
 create mode 100644 lib/eal/sw_64/include/rte_ticketlock.h
 create mode 100644 lib/eal/sw_64/include/rte_vect.h
 create mode 100644 lib/eal/sw_64/meson.build
 create mode 100644 lib/eal/sw_64/rte_cpuflags.c
 create mode 100644 lib/eal/sw_64/rte_cycles.c
 create mode 100644 lib/eal/sw_64/rte_hypervisor.c
 create mode 100644 lib/eal/sw_64/rte_power_intrinsics.c
 create mode 100644 lib/lpm/rte_lpm_sw.h

diff --git a/app/test/test_xmmt_ops.h b/app/test/test_xmmt_ops.h
index 626aa9b..944bcac 100644
--- a/app/test/test_xmmt_ops.h
+++ b/app/test/test_xmmt_ops.h
@@ -77,6 +77,22 @@ vect_set_epi32(int i3, int i2, int i1, int i0)
 
 	return data;
 }
+
+#elif defined(RTE_ARCH_SW_64)
+
+#define vect_loadu_sil128(p) (*(xmm_t *)p)
+
+static __rte_always_inline xmm_t
+vect_set_epi32(int i3, int i2, int i1, int i0)
+{
+        uint64_t h = ((uint64_t)i2 & 0xffffffff) | ((uint64_t)i3 << 32);
+        uint64_t l = ((uint64_t)i0 & 0xffffffff) | ((uint64_t)i1 << 32);
+
+        xmm_t data = {l,h};
+
+        return data;
+}
+
 #endif
 
 #endif /* _TEST_XMMT_OPS_H_ */
diff --git a/config/meson.build b/config/meson.build
index 6ae32ec..873b647 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -169,6 +169,8 @@ if not is_ms_compiler
         machine_args += '-mcpu=' + cpu_instruction_set
         machine_args += '-mtune=' + cpu_instruction_set
         compiler_arch_support = cc.has_argument('-mcpu=' + cpu_instruction_set)
+    elif host_machine.cpu_family().startswith('sw_64')
+        compiler_arch_support = true
     else
         machine_args += '-march=' + cpu_instruction_set
         # arm manages generic/auto config in config/arm/meson.build
diff --git a/config/sw_64/meson.build b/config/sw_64/meson.build
new file mode 100644
index 0000000..9575a5c
--- /dev/null
+++ b/config/sw_64/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
+
+if not dpdk_conf.get('RTE_ARCH_64')
+	error('Only 64-bit compiles are supported for this platform type')
+endif
+dpdk_conf.set('RTE_ARCH', 'sw_64')
+dpdk_conf.set('RTE_ARCH_SW_64', 1)
+dpdk_conf.set('RTE_MAX_LCORE', 1536)
+dpdk_conf.set('RTE_MAX_NUMA_NODES', 32)
+dpdk_conf.set('RTE_CACHE_LINE_SIZE', 128)
+dpdk_conf.set('RTE_FORCE_INTRINSICS', 'y')
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 9aa5fac..ae31f77 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -3640,6 +3640,58 @@ i40e_set_default_pctype_table(struct rte_eth_dev *dev)
 	}
 }
 
+#if defined __sw_64__
+int
+i40e_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
+{
+        return -1;
+}
+
+uint16_t
+i40e_recv_pkts_vec(
+        void __rte_unused *rx_queue,
+        struct rte_mbuf __rte_unused **rx_pkts,
+        uint16_t __rte_unused nb_pkts)
+{
+        return 0;
+}
+
+uint16_t
+i40e_recv_scattered_pkts_vec(
+        void __rte_unused *rx_queue,
+        struct rte_mbuf __rte_unused **rx_pkts,
+        uint16_t __rte_unused nb_pkts)
+{
+        return 0;
+}
+
+int
+i40e_rxq_vec_setup(struct i40e_rx_queue __rte_unused *rxq)
+{
+        return -1;
+}
+
+int
+i40e_txq_vec_setup(struct i40e_tx_queue __rte_unused *txq)
+{
+        return -1;
+}
+
+void
+i40e_rx_queue_release_mbufs_vec(struct i40e_rx_queue __rte_unused*rxq)
+{
+        return;
+}
+
+uint16_t
+i40e_xmit_fixed_burst_vec(void __rte_unused * tx_queue,
+                          struct rte_mbuf __rte_unused **tx_pkts,
+                          uint16_t __rte_unused nb_pkts)
+{
+        return 0;
+}
+#endif
+
 #ifndef RTE_ARCH_X86
 uint16_t
 i40e_recv_pkts_vec_avx2(void __rte_unused *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 90b0a70..ffe7fef 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -6066,7 +6066,7 @@ ixgbe_config_rss_filter(struct rte_eth_dev *dev,
  * RTE_ARCH_LOONGARCH is set.
  */
 #if defined(RTE_ARCH_PPC_64) || defined(RTE_ARCH_RISCV) || \
-	defined(RTE_ARCH_LOONGARCH)
+	defined(RTE_ARCH_LOONGARCH) || defined(RTE_ARCH_SW_64)
 int
 ixgbe_rx_vec_dev_conf_condition_check(struct rte_eth_dev __rte_unused *dev)
 {
diff --git a/drivers/net/memif/rte_eth_memif.h b/drivers/net/memif/rte_eth_memif.h
index f21806c..08a51fa 100644
--- a/drivers/net/memif/rte_eth_memif.h
+++ b/drivers/net/memif/rte_eth_memif.h
@@ -188,6 +188,8 @@ const char *memif_version(void);
 #define __NR_memfd_create 279
 #elif defined __loongarch__
 #define __NR_memfd_create 279
+#elif defined __sw_64__
+#define __NR_memfd_create 512
 #else
 #error "__NR_memfd_create unknown for this architecture"
 #endif
diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h
index 0d38bc1..58962b3 100644
--- a/drivers/net/tap/tap_bpf.h
+++ b/drivers/net/tap/tap_bpf.h
@@ -105,6 +105,8 @@ union bpf_attr {
 #  define __NR_bpf 280
 # elif defined(__loongarch__)
 #  define __NR_bpf 280
+# elif defined(__sw_64__)
+#  define __NR_bpf 170
 # else
 #  error __NR_bpf not defined
 # endif
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index 40e102b..00796f1 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -255,6 +255,14 @@ em_mask_key(void *key, xmm_t mask)
 
 	return vect_and(data, mask);
 }
+#elif defined(RTE_ARCH_SW_64)
+static inline xmm_t
+em_mask_key(void *key, xmm_t mask)
+{
+	xmm_t data = (*(xmm_t *)key);
+
+	return vect_and(data, mask);
+}
 #else
 #error No vector engine (SSE, NEON, ALTIVEC) available, check your toolchain
 #endif
diff --git a/lib/eal/sw_64/include/meson.build b/lib/eal/sw_64/include/meson.build
new file mode 100644
index 0000000..8230b26
--- /dev/null
+++ b/lib/eal/sw_64/include/meson.build
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
+
+arch_headers = files(
+		'rte_byteorder.h',
+		'rte_cycles.h',
+		'rte_mcslock.h',
+		'rte_pause.h',
+		'rte_rwlock.h',
+		'rte_ticketlock.h',
+		'rte_atomic.h',
+		'rte_cpuflags.h',
+		'rte_io.h',
+		'rte_memcpy.h',
+		'rte_prefetch.h',
+		'rte_spinlock.h',
+		'rte_vect.h',
+		'rte_power_intrinsics.h',
+		'rte_pflock.h',
+)
+
+install_headers(arch_headers, subdir: get_option('include_subdir_arch'))
diff --git a/lib/eal/sw_64/include/rte_altivec.h b/lib/eal/sw_64/include/rte_altivec.h
new file mode 100644
index 0000000..1551a94
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_altivec.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) Mellanox 2020.
+ */
+
+#ifndef _RTE_ALTIVEC_H_
+#define _RTE_ALTIVEC_H_
+
+/* To include altivec.h, GCC version must be >= 4.8 */
+#include <altivec.h>
+
+/*
+ * Compilation workaround for PPC64 when AltiVec is fully enabled, e.g. std=c11.
+ * Otherwise there would be a type conflict between stdbool and altivec.
+ */
+#if defined(__PPC64__) && !defined(__APPLE_ALTIVEC__)
+#undef bool
+/* redefine as in stdbool.h */
+#define bool _Bool
+#endif
+
+#endif /* _RTE_ALTIVEC_H_ */
diff --git a/lib/eal/sw_64/include/rte_atomic.h b/lib/eal/sw_64/include/rte_atomic.h
new file mode 100644
index 0000000..d25058b
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_atomic.h
@@ -0,0 +1,48 @@
+#ifndef _RTE_ATOMIC_sw_64_H_
+#define _RTE_ATOMIC_sw_64_H_
+
+#ifndef RTE_FORCE_INTRINSICS
+//# error Platform must be built with CONFIG_RTE_FORCE_INTRINSICS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_atomic.h"
+
+#define swmb() asm volatile("memb": : :"memory")
+
+#define rte_mb() swmb()
+
+#define rte_wmb() swmb()
+
+#define rte_rmb() swmb()
+
+#define rte_smp_mb() swmb()
+
+#define rte_smp_wmb() swmb()
+
+#define rte_smp_rmb() swmb()
+
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_wmb()
+
+#define rte_io_rmb() rte_rmb()
+
+#define rte_cio_rmb() rte_rmb()
+
+#define rte_cio_wmb() rte_wmb()
+
+static __rte_always_inline void
+rte_atomic_thread_fence(int memorder)
+{
+	__atomic_thread_fence(memorder);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ATOMIC_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_byteorder.h b/lib/eal/sw_64/include/rte_byteorder.h
new file mode 100644
index 0000000..b8b23ef
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_byteorder.h
@@ -0,0 +1,57 @@
+#ifndef _RTE_BYTEORDER_sw_64_H_
+#define _RTE_BYTEORDER_sw_64_H_
+
+#ifndef RTE_FORCE_INTRINSICS
+//#  error Platform must be built with CONFIG_RTE_FORCE_INTRINSICS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_byteorder.h"
+#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+#define rte_bswap16(x) rte_constant_bswap16(x)
+#endif
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define rte_cpu_to_le_16(x) (x)
+#define rte_cpu_to_le_32(x) (x)
+#define rte_cpu_to_le_64(x) (x)
+
+#define rte_cpu_to_be_16(x) rte_bswap16(x)
+#define rte_cpu_to_be_32(x) rte_bswap32(x)
+#define rte_cpu_to_be_64(x) rte_bswap64(x)
+
+#define rte_le_to_cpu_16(x) (x)
+#define rte_le_to_cpu_32(x) (x)
+#define rte_le_to_cpu_64(x) (x)
+
+#define rte_be_to_cpu_16(x) rte_bswap16(x)
+#define rte_be_to_cpu_32(x) rte_bswap32(x)
+#define rte_be_to_cpu_64(x) rte_bswap64(x)
+
+#else /* RTE_BIG_ENDIAN */
+
+#define rte_cpu_to_le_16(x) rte_bswap16(x)
+#define rte_cpu_to_le_32(x) rte_bswap32(x)
+#define rte_cpu_to_le_64(x) rte_bswap64(x)
+
+#define rte_cpu_to_be_16(x) (x)
+#define rte_cpu_to_be_32(x) (x)
+#define rte_cpu_to_be_64(x) (x)
+
+#define rte_le_to_cpu_16(x) rte_bswap16(x)
+#define rte_le_to_cpu_32(x) rte_bswap32(x)
+#define rte_le_to_cpu_64(x) rte_bswap64(x)
+
+#define rte_be_to_cpu_16(x) (x)
+#define rte_be_to_cpu_32(x) (x)
+#define rte_be_to_cpu_64(x) (x)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/eal/sw_64/include/rte_cpuflags.h b/lib/eal/sw_64/include/rte_cpuflags.h
new file mode 100644
index 0000000..48fde25
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_cpuflags.h
@@ -0,0 +1,20 @@
+#ifndef _RTE_CPUFLAGS_sw_64_H_
+#define _RTE_CPUFLAGS_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enumeration of all CPU features supported */
+
+enum rte_cpu_flag_t {
+	RTE_CPUFLAG_NUMFLAGS /**< This should always be the last! */
+	};
+
+#include "generic/rte_cpuflags.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CPUFLAGS_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_cycles.h b/lib/eal/sw_64/include/rte_cycles.h
new file mode 100644
index 0000000..22433b4
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_cycles.h
@@ -0,0 +1,35 @@
+#ifndef _RTE_CYCLES_sw_64_H_
+#define _RTE_CYCLES_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_cycles.h"
+
+static inline uint64_t
+rte_rdtsc(void)
+{
+	uint64_t u64_TSC;
+	asm volatile("RTC %0":"=r"(u64_TSC));
+	return u64_TSC;
+}
+
+static inline uint64_t
+rte_rdtsc_precise(void)
+{
+	rte_mb();
+	return rte_rdtsc();
+}
+
+static inline uint64_t
+rte_get_tsc_cycles(void)
+{
+	return rte_rdtsc();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CYCLES_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_io.h b/lib/eal/sw_64/include/rte_io.h
new file mode 100644
index 0000000..058ada5
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_io.h
@@ -0,0 +1,14 @@
+#ifndef _RTE_IO_sw_64_H_
+#define _RTE_IO_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_io.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_IO_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_mcslock.h b/lib/eal/sw_64/include/rte_mcslock.h
new file mode 100644
index 0000000..a900443
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_mcslock.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Arm Limited
+ */
+
+#ifndef _RTE_MCSLOCK_sw_64_H_
+#define _RTE_MCSLOCK_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_mcslock.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_MCSLOCK_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_memcpy.h b/lib/eal/sw_64/include/rte_memcpy.h
new file mode 100644
index 0000000..24069e9
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_memcpy.h
@@ -0,0 +1,60 @@
+#ifndef _RTE_MEMCPY_sw_64_H_
+#define _RTE_MEMCPY_sw_64_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <string.h>
+
+#include "generic/rte_memcpy.h"
+
+static inline void
+rte_mov16(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 16);
+}
+
+static inline void
+rte_mov32(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 32);
+}
+
+static inline void
+rte_mov48(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 48);
+}
+
+static inline void
+rte_mov64(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 64);
+}
+
+static inline void
+rte_mov128(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 128);
+}
+
+static inline void
+rte_mov256(uint8_t *dst, const uint8_t *src)
+{
+	memcpy(dst, src, 256);
+}
+
+#define rte_memcpy(d, s, n)     memcpy((d), (s), (n))
+
+static inline void *
+rte_memcpy_func(void *dst, const void *src, size_t n)
+{
+	return memcpy(dst, src, n);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_MEMCPY_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_pause.h b/lib/eal/sw_64/include/rte_pause.h
new file mode 100644
index 0000000..559ed6a
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_pause.h
@@ -0,0 +1,20 @@
+#ifndef _RTE_PAUSE_sw_64_H_
+#define _RTE_PAUSE_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include "generic/rte_pause.h"
+
+static inline void rte_pause(void)
+{
+	asm volatile("memb" ::: "memory");
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PAUSE_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_pflock.h b/lib/eal/sw_64/include/rte_pflock.h
new file mode 100644
index 0000000..bb9934e
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_pflock.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Microsoft Corporation
+ */
+
+#ifndef _RTE_PFLOCK_ARM_H_
+#define _RTE_PFLOCK_ARM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_pflock.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PFLOCK_ARM_H_ */
diff --git a/lib/eal/sw_64/include/rte_power_intrinsics.h b/lib/eal/sw_64/include/rte_power_intrinsics.h
new file mode 100644
index 0000000..c0e9ac2
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_power_intrinsics.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#ifndef _RTE_POWER_INTRINSIC_PPC_H_
+#define _RTE_POWER_INTRINSIC_PPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+
+#include "generic/rte_power_intrinsics.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_POWER_INTRINSIC_PPC_H_ */
diff --git a/lib/eal/sw_64/include/rte_prefetch.h b/lib/eal/sw_64/include/rte_prefetch.h
new file mode 100644
index 0000000..3ff322a
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_prefetch.h
@@ -0,0 +1,47 @@
+#ifndef _RTE_PREFETCH_sw_64_H_
+#define _RTE_PREFETCH_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include "generic/rte_prefetch.h"
+
+static inline void
+rte_prefetch0(const volatile void *p)
+{
+	__builtin_prefetch((const void *)(uintptr_t)p, 0, 3);
+}
+
+static inline void
+rte_prefetch1(const volatile void *p)
+{
+	__builtin_prefetch((const void *)(uintptr_t)p, 0, 2);
+}
+
+static inline void
+rte_prefetch2(const volatile void *p)
+{
+	__builtin_prefetch((const void *)(uintptr_t)p, 0, 1);
+}
+
+static inline void
+rte_prefetch_non_temporal(const volatile void *p)
+{
+	/* non-temporal version not available, fallback to rte_prefetch0 */
+	rte_prefetch0(p);
+}
+
+__rte_experimental
+static inline void
+rte_cldemote(const volatile void *p)
+{
+	        RTE_SET_USED(p);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PREFETCH_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_rwlock.h b/lib/eal/sw_64/include/rte_rwlock.h
new file mode 100644
index 0000000..4b08ef4
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_rwlock.h
@@ -0,0 +1,38 @@
+#ifndef _RTE_RWLOCK_sw_64_H_
+#define _RTE_RWLOCK_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_rwlock.h"
+
+static inline void
+rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_read_lock(rwl);
+}
+
+static inline void
+rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_read_unlock(rwl);
+}
+
+static inline void
+rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_write_lock(rwl);
+}
+
+static inline void
+rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_write_unlock(rwl);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RWLOCK_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_spinlock.h b/lib/eal/sw_64/include/rte_spinlock.h
new file mode 100644
index 0000000..2be4c42
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_spinlock.h
@@ -0,0 +1,57 @@
+#ifndef _RTE_SPINLOCK_sw_64_H_
+#define _RTE_SPINLOCK_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_spinlock.h"
+#include "rte_common.h"
+
+static inline int
+rte_tm_supported(void)
+{
+	return 0;
+}
+
+static inline void
+rte_spinlock_lock_tm(rte_spinlock_t *sl)
+{
+	rte_spinlock_lock(sl); /* fall-back */
+}
+
+static inline int
+rte_spinlock_trylock_tm(rte_spinlock_t *sl)
+{
+	return rte_spinlock_trylock(sl);
+}
+
+static inline void
+rte_spinlock_unlock_tm(rte_spinlock_t *sl)
+{
+	rte_spinlock_unlock(sl);
+}
+
+static inline void
+rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)
+{
+	rte_spinlock_recursive_lock(slr); /* fall-back */
+}
+
+static inline void
+rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)
+{
+	rte_spinlock_recursive_unlock(slr);
+}
+
+static inline int
+rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)
+{
+	return rte_spinlock_recursive_trylock(slr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_SPINLOCK_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_ticketlock.h b/lib/eal/sw_64/include/rte_ticketlock.h
new file mode 100644
index 0000000..bf081c1
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_ticketlock.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Arm Limited
+ */
+
+#ifndef _RTE_TICKETLOCK_sw_64_H_
+#define _RTE_TICKETLOCK_sw_64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_ticketlock.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_TICKETLOCK_sw_64_H_ */
diff --git a/lib/eal/sw_64/include/rte_vect.h b/lib/eal/sw_64/include/rte_vect.h
new file mode 100644
index 0000000..e3e76d8
--- /dev/null
+++ b/lib/eal/sw_64/include/rte_vect.h
@@ -0,0 +1,55 @@
+#ifndef _RTE_VECT_sw_64_H_
+#define _RTE_VECT_sw_64_H_
+
+#include <stdint.h>
+#include "generic/rte_vect.h"
+#include "rte_debug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_256
+
+typedef struct _xmm_t
+{
+	uint64_t u64_L;
+	uint64_t u64_H;
+}xmm_t;
+
+#define XMM_SIZE        (sizeof(xmm_t))
+#define XMM_MASK        (XMM_SIZE - 1)
+
+typedef union rte_xmm {
+	xmm_t    x;
+	uint8_t  u8[XMM_SIZE / sizeof(uint8_t)];
+	uint16_t u16[XMM_SIZE / sizeof(uint16_t)];
+	uint32_t u32[XMM_SIZE / sizeof(uint32_t)];
+	uint64_t u64[XMM_SIZE / sizeof(uint64_t)];
+	double   pd[XMM_SIZE / sizeof(double)];
+} rte_xmm_t;
+
+static inline xmm_t
+vect_load_128(void *p)
+{
+        xmm_t ret = *((xmm_t *)p);
+
+        return ret;
+}
+
+static inline xmm_t
+vect_and(xmm_t data, xmm_t mask)
+{
+        rte_xmm_t ret = {.x = data };
+        rte_xmm_t m = {.x = mask };
+        ret.u64[0] &= m.u64[0];
+        ret.u64[1] &= m.u64[1];
+
+        return ret.x;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/eal/sw_64/meson.build b/lib/eal/sw_64/meson.build
new file mode 100644
index 0000000..43c4654
--- /dev/null
+++ b/lib/eal/sw_64/meson.build
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
+
+subdir('include')
+
+sources += files(
+	'rte_cpuflags.c',
+	'rte_cycles.c',
+	'rte_hypervisor.c',
+	'rte_power_intrinsics.c',
+)
diff --git a/lib/eal/sw_64/rte_cpuflags.c b/lib/eal/sw_64/rte_cpuflags.c
new file mode 100644
index 0000000..efdc174
--- /dev/null
+++ b/lib/eal/sw_64/rte_cpuflags.c
@@ -0,0 +1,18 @@
+#include "rte_cpuflags.h"
+#include <errno.h>
+
+/**
+ * Checks if a particular flag is available on current machine.
+ */
+
+int
+rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature)
+{
+	return -ENOENT;
+}
+
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
+{
+	memset(intrinsics, 0, sizeof(*intrinsics));
+}
diff --git a/lib/eal/sw_64/rte_cycles.c b/lib/eal/sw_64/rte_cycles.c
new file mode 100644
index 0000000..851fd02
--- /dev/null
+++ b/lib/eal/sw_64/rte_cycles.c
@@ -0,0 +1,7 @@
+#include "eal_private.h"
+
+uint64_t
+get_tsc_freq_arch(void)
+{
+	return 0;
+}
diff --git a/lib/eal/sw_64/rte_hypervisor.c b/lib/eal/sw_64/rte_hypervisor.c
new file mode 100644
index 0000000..08a1c97
--- /dev/null
+++ b/lib/eal/sw_64/rte_hypervisor.c
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 Mellanox Technologies, Ltd
+ */
+
+#include "rte_hypervisor.h"
+
+enum rte_hypervisor
+rte_hypervisor_get(void)
+{
+	return RTE_HYPERVISOR_UNKNOWN;
+}
diff --git a/lib/eal/sw_64/rte_power_intrinsics.c b/lib/eal/sw_64/rte_power_intrinsics.c
new file mode 100644
index 0000000..59a838f
--- /dev/null
+++ b/lib/eal/sw_64/rte_power_intrinsics.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#include <errno.h>
+
+#include "rte_power_intrinsics.h"
+
+/**
+ * This function is not supported on SW.
+ */
+int
+rte_power_monitor(const struct rte_power_monitor_cond *pmc,
+		const uint64_t tsc_timestamp)
+{
+	RTE_SET_USED(pmc);
+	RTE_SET_USED(tsc_timestamp);
+
+	return -ENOTSUP;
+}
+
+/**
+ * This function is not supported on SW.
+ */
+int
+rte_power_pause(const uint64_t tsc_timestamp)
+{
+	RTE_SET_USED(tsc_timestamp);
+
+	return -ENOTSUP;
+}
+
+/**
+ * This function is not supported on SW.
+ */
+int
+rte_power_monitor_wakeup(const unsigned int lcore_id)
+{
+	RTE_SET_USED(lcore_id);
+
+	return -ENOTSUP;
+}
+
+int
+rte_power_monitor_multi(const struct rte_power_monitor_cond pmc[],
+                const uint32_t num, const uint64_t tsc_timestamp)
+{
+        RTE_SET_USED(pmc);
+        RTE_SET_USED(num);
+        RTE_SET_USED(tsc_timestamp);
+
+        return -ENOTSUP;
+}
diff --git a/lib/lpm/rte_lpm.h b/lib/lpm/rte_lpm.h
index f57977b..4e95bcb 100644
--- a/lib/lpm/rte_lpm.h
+++ b/lib/lpm/rte_lpm.h
@@ -405,6 +405,8 @@ rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
 #include "rte_lpm_altivec.h"
 #elif defined(RTE_ARCH_X86)
 #include "rte_lpm_sse.h"
+#elif defined(RTE_ARCH_SW_64)
+#include "rte_lpm_sw.h"
 #else
 #include "rte_lpm_scalar.h"
 #endif
diff --git a/lib/lpm/rte_lpm_sw.h b/lib/lpm/rte_lpm_sw.h
new file mode 100644
index 0000000..d93d8e6
--- /dev/null
+++ b/lib/lpm/rte_lpm_sw.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#ifndef _RTE_LPM_SW_H_
+#define _RTE_LPM_SW_H_
+
+#include <rte_branch_prediction.h>
+#include <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_vect.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void
+rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
+	uint32_t defv)
+{
+	uint32_t i24[4];
+	rte_xmm_t i8;
+	uint32_t tbl[4];
+	uint64_t idx, pt, pt2;
+	const uint32_t *ptbl;
+
+	const uint32_t mask8[4] =
+		{(uint32_t)UINT8_MAX, (uint32_t)UINT8_MAX, (uint32_t)UINT8_MAX, (uint32_t)UINT8_MAX};
+
+	/*
+	 * RTE_LPM_VALID_EXT_ENTRY_BITMASK for 2 LPM entries
+	 * as one 64-bit value (0x0300000003000000).
+	 */
+	const uint64_t mask_xv =
+		((uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK |
+		(uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 32);
+
+	/*
+	 * RTE_LPM_LOOKUP_SUCCESS for 2 LPM entries
+	 * as one 64-bit value (0x0100000001000000).
+	 */
+	const uint64_t mask_v =
+		((uint64_t)RTE_LPM_LOOKUP_SUCCESS |
+		(uint64_t)RTE_LPM_LOOKUP_SUCCESS << 32);
+
+	/* get 4 indexes for tbl24[]. */
+	i24[0] = (uint32_t)ip.u64_L >> CHAR_BIT;
+	i24[1] = (uint32_t)(ip.u64_L >> 32) >> CHAR_BIT;
+	i24[2] = (uint32_t)ip.u64_H >> CHAR_BIT;
+	i24[3] = (uint32_t)(ip.u64_H >> 32) >> CHAR_BIT;
+
+	/* extract values from tbl24[] */
+	idx = ((uint64_t)i24[0] & 0xffffffff) | ((uint64_t)i24[1] << 32);
+
+	ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
+	tbl[0] = *ptbl;
+	ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
+	tbl[1] = *ptbl;
+
+	idx = ((uint64_t)i24[2] | (uint64_t)i24[3] << 32);
+
+	ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
+	tbl[2] = *ptbl;
+	ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
+	tbl[3] = *ptbl;
+
+	/* get 4 indexes for tbl8[]. */
+	i8.x.u64_L = (ip.u64_L & (0x000000FF000000FF));
+	i8.x.u64_H = (ip.u64_H & (0x000000FF000000FF));
+
+
+	pt = (uint64_t)tbl[0] |
+		(uint64_t)tbl[1] << 32;
+	pt2 = (uint64_t)tbl[2] |
+		(uint64_t)tbl[3] << 32;
+
+	/* search successfully finished for all 4 IP addresses. */
+	if (likely((pt & mask_xv) == mask_v) &&
+			likely((pt2 & mask_xv) == mask_v)) {
+		*(uint64_t *)hop = pt & RTE_LPM_MASKX4_RES;
+		*(uint64_t *)(hop + 2) = pt2 & RTE_LPM_MASKX4_RES;
+		return;
+	}
+
+	if (unlikely((pt & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[0] = i8.u32[0] +
+			(uint8_t)tbl[0] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[0]];
+		tbl[0] = *ptbl;
+	}
+	if (unlikely((pt >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[1] = i8.u32[1] +
+			(uint8_t)tbl[1] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[1]];
+		tbl[1] = *ptbl;
+	}
+	if (unlikely((pt2 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[2] = i8.u32[2] +
+			(uint8_t)tbl[2] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[2]];
+		tbl[2] = *ptbl;
+	}
+	if (unlikely((pt2 >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
+			RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
+		i8.u32[3] = i8.u32[3] +
+			(uint8_t)tbl[3] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
+		ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[3]];
+		tbl[3] = *ptbl;
+	}
+
+	hop[0] = (tbl[0] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[0] & 0x00FFFFFF : defv;
+	hop[1] = (tbl[1] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[1] & 0x00FFFFFF : defv;
+	hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[2] & 0x00FFFFFF : defv;
+	hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[3] & 0x00FFFFFF : defv;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_LPM_SW_H_ */
diff --git a/meson.build b/meson.build
index 5e161f4..88696f6 100644
--- a/meson.build
+++ b/meson.build
@@ -62,6 +62,8 @@ elif host_machine.cpu_family().startswith('ppc')
     arch_subdir = 'ppc'
 elif host_machine.cpu_family().startswith('riscv')
     arch_subdir = 'riscv'
+elif host_machine.cpu_family().startswith('sw_64')
+    arch_subdir = 'sw_64'
 endif
 
 # configure the build, and make sure configs here and in config folder are
-- 
2.43.5

