@@ -295,6 +295,12 @@ F: app/*/*_neon.*
F: examples/*/*_neon.*
F: examples/common/neon/
+LoongArch
+M: Min Zhou <zhoumin@loongson.cn>
+F: config/loongarch/
+F: doc/guides/linux_gsg/cross_build_dpdk_for_loongarch.rst
+F: lib/eal/loongarch/
+
IBM POWER (alpha)
M: David Christensen <drc@linux.vnet.ibm.com>
F: config/ppc/
@@ -65,6 +65,18 @@ vect_set_epi32(int i3, int i2, int i1, int i0)
return data;
}
+#elif defined(RTE_ARCH_LOONGARCH)
+
+#define vect_loadu_sil128(p) vect_load_128(p)
+
+/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */
+static __rte_always_inline xmm_t
+vect_set_epi32(int i3, int i2, int i1, int i0)
+{
+ xmm_t data = (xmm_t){.u32 = {i0, i1, i2, i3}};
+
+ return data;
+}
#endif
#endif /* _TEST_XMMT_OPS_H_ */
new file mode 100644
@@ -0,0 +1,16 @@
+[binaries]
+c = 'loongarch64-unknown-linux-gnu-gcc'
+cpp = 'loongarch64-unknown-linux-gnu-cpp'
+ar = 'loongarch64-unknown-linux-gnu-gcc-ar'
+strip = 'loongarch64-unknown-linux-gnu-strip'
+pcap-config = ''
+
+[host_machine]
+system = 'linux'
+cpu_family = 'loongarch64'
+cpu = '3a5000'
+endian = 'little'
+
+[properties]
+implementor_id = 'generic'
+implementor_pn = 'default'
new file mode 100644
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 Loongson Technology Corporation Limited
+
+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', 'loongarch')
+dpdk_conf.set('RTE_ARCH_LOONGARCH', 1)
+dpdk_conf.set('RTE_FORCE_INTRINSICS', 1)
+
+machine_args_generic = [
+ ['default', ['-march=loongarch64']],
+]
+
+flags_generic = [
+ ['RTE_MACHINE', '"loongarch64"'],
+ ['RTE_MAX_LCORE', 64],
+ ['RTE_MAX_NUMA_NODES', 16],
+ ['RTE_CACHE_LINE_SIZE', 64]]
+
+impl_generic = ['Generic loongarch', flags_generic, machine_args_generic]
+
+machine = []
+machine_args = []
+
+machine = impl_generic
+impl_pn = 'default'
+
+message('Implementer : ' + machine[0])
+foreach flag: machine[1]
+ if flag.length() > 0
+ dpdk_conf.set(flag[0], flag[1])
+ endif
+endforeach
+
+foreach marg: machine[2]
+ if marg[0] == impl_pn
+ foreach f: marg[1]
+ machine_args += f
+ endforeach
+ endif
+endforeach
+message(machine_args)
@@ -42,7 +42,7 @@ Per Architecture Sources
The following macro options can be used:
* ``RTE_ARCH`` is a string that contains the name of the architecture.
-* ``RTE_ARCH_I686``, ``RTE_ARCH_X86_64``, ``RTE_ARCH_X86_X32``, ``RTE_ARCH_PPC_64``, ``RTE_ARCH_RISCV``, ``RTE_ARCH_ARM``, ``RTE_ARCH_ARMv7`` or ``RTE_ARCH_ARM64`` are defined only if we are building for those architectures.
+* ``RTE_ARCH_I686``, ``RTE_ARCH_X86_64``, ``RTE_ARCH_X86_X32``, ``RTE_ARCH_PPC_64``, ``RTE_ARCH_RISCV``, ``RTE_ARCH_LOONGARCH``, ``RTE_ARCH_ARM``, ``RTE_ARCH_ARMv7`` or ``RTE_ARCH_ARM64`` are defined only if we are building for those architectures.
Per Execution Environment Sources
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
new file mode 100644
@@ -0,0 +1,87 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2022 Loongson Technology Corporation Limited
+
+Cross compiling DPDK for LoongArch
+==================================
+
+This chapter describes how to cross compile DPDK for LoongArch from x86 build
+hosts.
+
+.. note::
+
+ Due to some of the code under review, the current Linux 5.19 cannot boot
+ on LoongArch system. There are still some Linux distributions that have
+ supported LoongArch host, such as Anolis OS, Kylin, Loongnix and UOS. These
+ distributions base on Linux kernel 4.19 supported by Loongson Corporation.
+ Because LoongArch is such a new platform with many fundamental pieces of
+ software still under development, it is currently recommended to cross
+ compile DPDK on x86 for LoongArch.
+
+
+Prerequisites
+-------------
+
+Ensure that you have all pre-requisites for building DPDK natively as those
+will be required also for cross-compilation.
+
+Linux kernel
+~~~~~~~~~~~~
+
+Make sure that LoongArch host is running Linux kernel 4.19 or newer supported
+by Loongson Corporation. The support for LoongArch in the current Linux 5.19
+is not complete because it still misses some patches to add for other
+subsystems.
+
+GNU toolchain
+-------------
+
+Obtain the cross toolchain
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The build process was tested using:
+
+* Latest `LoongArch GNU toolchain
+ <https://github.com/loongson/build-tools/releases/download/2022.08.11/loongarch64-clfs-5.1-cross-tools-gcc-glibc.tar.xz>`_
+ on Debian 10.4 or CentOS 8.
+
+Alternatively the toolchain may be built straight from the source via CLFS, to
+do that follow the instructions on `CLFS for LoongArch64
+<https://github.com/sunhaiyong1978/CLFS-for-LoongArch>`_ github page.
+
+To download cross tools from github we can use the following command:
+
+.. code-block:: console
+
+ wget -P /tmp/ https://github.com/loongson/build-tools/releases/download/2022.08.11/loongarch64-clfs-5.1-cross-tools-gcc-glibc.tar.xz
+
+Unzip and add into the PATH
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After downloading the cross-tools file, we need unzip and add those executable
+binaries into the PATH as follows:
+
+.. code-block:: console
+
+ tar -xvf /tmp/loongarch64-clfs-5.1-cross-tools-gcc-glibc.tar.xz -C <cross_tool_install_dir> --strip-components 1
+ export PATH=$PATH:<cross_tool_install_dir>/bin
+
+
+Cross Compiling DPDK with GNU toolchain using Meson
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To cross-compile DPDK for generic LoongArch we can use the following command:
+
+.. code-block:: console
+
+ meson cross-build --cross-file config/loongarch/loongarch_loongarch64_linux_gcc
+ ninja -C cross-build
+
+Supported cross-compilation targets
+-----------------------------------
+
+Currently the following target is supported:
+
+* Generic LoongArch64 ISA: ``config/loongarch/loongarch_loongarch64_linux_gcc``
+
+To add a new target support, a corresponding cross-file has to be added to
+``config/loongarch`` directory.
@@ -14,6 +14,7 @@ Getting Started Guide for Linux
sys_reqs
build_dpdk
cross_build_dpdk_for_arm64
+ cross_build_dpdk_for_loongarch
cross_build_dpdk_for_riscv
linux_drivers
build_sample_apps
@@ -832,6 +832,14 @@ ARMv8
Support armv8a (64bit) architecture.
+.. _nic_features_loongarch64:
+
+LoongArch64
+-----------
+
+Support 64-bit LoongArch architecture.
+
+
.. _nic_features_power8:
Power8
@@ -71,6 +71,7 @@ Linux =
Windows =
ARMv7 =
ARMv8 =
+LoongArch64 =
Power8 =
rv64 =
x86-32 =
@@ -55,6 +55,13 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Added initial LoongArch architecture support.**
+
+ Added EAL implementation for LoongArch architecture. The initial devices
+ the porting was tested on included Loongson 3A5000, Loongson 3C5000 and
+ Loongson 3C5000L. In theory this implementation should work with any target
+ based on ``LoongArch`` ISA.
+
Removed Items
-------------
@@ -7,6 +7,12 @@ if arch_subdir == 'riscv'
subdir_done()
endif
+if arch_subdir == 'loongarch'
+ build = false
+ reason = 'not supported on LoongArch'
+ subdir_done()
+endif
+
cflags += ['-DPF_DRIVER',
'-DVF_DRIVER',
'-DINTEGRATED_VF',
@@ -1,6 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+if arch_subdir == 'loongarch'
+ build = false
+ reason = 'not supported on LoongArch'
+ subdir_done()
+endif
+
cflags += ['-DRTE_LIBRTE_IXGBE_BYPASS']
subdir('base')
@@ -1,6 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018-2019 Cisco Systems, Inc. All rights reserved.
+if arch_subdir == 'loongarch'
+ build = false
+ reason = 'not supported on LoongArch'
+ subdir_done()
+endif
+
if not is_linux
build = false
reason = 'only supported on Linux'
@@ -1,6 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 Luca Boccassi <bluca@debian.org>
+if arch_subdir == 'loongarch'
+ build = false
+ reason = 'not supported on LoongArch'
+ subdir_done()
+endif
+
if not is_linux
build = false
reason = 'only supported on Linux'
@@ -6,6 +6,12 @@
# To build this example as a standalone application with an already-installed
# DPDK instance, use 'make'
+if arch_subdir == 'loongarch'
+ build = false
+ reason = 'not supported on LoongArch'
+ subdir_done()
+endif
+
allow_experimental_apis = true
deps += ['acl', 'hash', 'lpm', 'fib', 'eventdev']
sources = files(
@@ -77,7 +77,11 @@ uint64_t eal_get_baseaddr(void)
* rte_mem_check_dma_mask for ensuring all memory is within supported
* range.
*/
+#if defined(RTE_ARCH_LOONGARCH)
+ return 0x7000000000ULL;
+#else
return 0x100000000ULL;
+#endif
}
/*
new file mode 100644
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 Loongson Technology Corporation Limited
+
+arch_headers = files(
+ 'rte_atomic.h',
+ 'rte_byteorder.h',
+ 'rte_cpuflags.h',
+ 'rte_cycles.h',
+ 'rte_io.h',
+ 'rte_memcpy.h',
+ 'rte_pause.h',
+ 'rte_power_intrinsics.h',
+ 'rte_prefetch.h',
+ 'rte_rwlock.h',
+ 'rte_spinlock.h',
+ 'rte_vect.h',
+)
+install_headers(arch_headers, subdir: get_option('include_subdir_arch'))
new file mode 100644
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_ATOMIC_LOONGARCH_H_
+#define _RTE_ATOMIC_LOONGARCH_H_
+
+#ifndef RTE_FORCE_INTRINSICS
+# error Platform must be built with RTE_FORCE_INTRINSICS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include "generic/rte_atomic.h"
+
+#define rte_mb() do { asm volatile("dbar 0":::"memory"); } while (0)
+
+#define rte_wmb() rte_mb()
+
+#define rte_rmb() rte_mb()
+
+#define rte_smp_mb() rte_mb()
+
+#define rte_smp_wmb() rte_mb()
+
+#define rte_smp_rmb() rte_mb()
+
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_mb()
+
+#define rte_io_rmb() rte_mb()
+
+static __rte_always_inline void
+rte_atomic_thread_fence(int memorder)
+{
+ __atomic_thread_fence(memorder);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ATOMIC_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_BYTEORDER_LOONGARCH_H_
+#define _RTE_BYTEORDER_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_byteorder.h"
+
+#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 */
+#error "LoongArch not support big endian!"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BYTEORDER_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_CPUFLAGS_LOONGARCH_H_
+#define _RTE_CPUFLAGS_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Enumeration of all CPU features supported
+ */
+enum rte_cpu_flag_t {
+ RTE_CPUFLAG_CPUCFG = 0,
+ RTE_CPUFLAG_LAM,
+ RTE_CPUFLAG_UAL,
+ RTE_CPUFLAG_FPU,
+ RTE_CPUFLAG_LSX,
+ RTE_CPUFLAG_LASX,
+ RTE_CPUFLAG_CRC32,
+ RTE_CPUFLAG_COMPLEX,
+ RTE_CPUFLAG_CRYPTO,
+ RTE_CPUFLAG_LVZ,
+ RTE_CPUFLAG_LBT_X86,
+ RTE_CPUFLAG_LBT_ARM,
+ RTE_CPUFLAG_LBT_MIPS,
+ /* The last item */
+ RTE_CPUFLAG_NUMFLAGS /**< This should always be the last! */
+};
+
+#include "generic/rte_cpuflags.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CPUFLAGS_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_CYCLES_LOONGARCH_H_
+#define _RTE_CYCLES_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_cycles.h"
+
+/**
+ * Read the time base register.
+ *
+ * @return
+ * The time base for this lcore.
+ */
+static inline uint64_t
+rte_rdtsc(void)
+{
+ uint64_t count;
+
+ __asm__ __volatile__ (
+ "rdtime.d %[cycles], $zero\n"
+ : [cycles] "=r" (count)
+ ::
+ );
+ return count;
+}
+
+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_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_IO_LOONGARCH_H_
+#define _RTE_IO_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_io.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_IO_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_MEMCPY_LOONGARCH_H_
+#define _RTE_MEMCPY_LOONGARCH_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#include "rte_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_MEMCPY_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_PAUSE_LOONGARCH_H_
+#define _RTE_PAUSE_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rte_atomic.h"
+
+#include "generic/rte_pause.h"
+
+static inline void rte_pause(void)
+{
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PAUSE_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_POWER_INTRINSIC_LOONGARCH_H_
+#define _RTE_POWER_INTRINSIC_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+
+#include "generic/rte_power_intrinsics.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_POWER_INTRINSIC_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_PREFETCH_LOONGARCH_H_
+#define _RTE_PREFETCH_LOONGARCH_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_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_RWLOCK_LOONGARCH_H_
+#define _RTE_RWLOCK_LOONGARCH_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_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_SPINLOCK_LOONGARCH_H_
+#define _RTE_SPINLOCK_LOONGARCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_common.h>
+#include "generic/rte_spinlock.h"
+
+#ifndef RTE_FORCE_INTRINSICS
+# error Platform must be built with RTE_FORCE_INTRINSICS
+#endif
+
+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_LOONGARCH_H_ */
new file mode 100644
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef _RTE_VECT_LOONGARCH_H_
+#define _RTE_VECT_LOONGARCH_H_
+
+#include <stdint.h>
+#include "generic/rte_vect.h"
+#include "rte_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_DISABLED
+
+typedef union xmm {
+ int8_t i8[16];
+ int16_t i16[8];
+ int32_t i32[4];
+ int64_t i64[2];
+ uint8_t u8[16];
+ uint16_t u16[8];
+ uint32_t u32[4];
+ uint64_t u64[2];
+ double pd[2];
+} __rte_aligned(16) 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_aligned(16) 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
new file mode 100644
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 Loongson Technology Corporation Limited
+
+subdir('include')
+
+sources += files(
+ 'rte_cpuflags.c',
+ 'rte_cycles.c',
+ 'rte_hypervisor.c',
+ 'rte_power_intrinsics.c',
+)
new file mode 100644
@@ -0,0 +1,93 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#include "rte_cpuflags.h"
+
+#include <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Symbolic values for the entries in the auxiliary table */
+#define AT_HWCAP 16
+
+/* software based registers */
+enum cpu_register_t {
+ REG_NONE = 0,
+ REG_HWCAP,
+ REG_MAX
+};
+
+typedef uint32_t hwcap_registers_t[REG_MAX];
+
+struct feature_entry {
+ uint32_t reg;
+ uint32_t bit;
+#define CPU_FLAG_NAME_MAX_LEN 64
+ char name[CPU_FLAG_NAME_MAX_LEN];
+};
+
+#define FEAT_DEF(name, reg, bit) \
+ [RTE_CPUFLAG_##name] = {reg, bit, #name},
+
+const struct feature_entry rte_cpu_feature_table[] = {
+ FEAT_DEF(CPUCFG, REG_HWCAP, 0)
+ FEAT_DEF(LAM, REG_HWCAP, 1)
+ FEAT_DEF(UAL, REG_HWCAP, 2)
+ FEAT_DEF(FPU, REG_HWCAP, 3)
+ FEAT_DEF(LSX, REG_HWCAP, 4)
+ FEAT_DEF(LASX, REG_HWCAP, 5)
+ FEAT_DEF(CRC32, REG_HWCAP, 6)
+ FEAT_DEF(COMPLEX, REG_HWCAP, 7)
+ FEAT_DEF(CRYPTO, REG_HWCAP, 8)
+ FEAT_DEF(LVZ, REG_HWCAP, 9)
+ FEAT_DEF(LBT_X86, REG_HWCAP, 10)
+ FEAT_DEF(LBT_ARM, REG_HWCAP, 11)
+ FEAT_DEF(LBT_MIPS, REG_HWCAP, 12)
+};
+
+/*
+ * Read AUXV software register and get cpu features for LoongArch
+ */
+static void
+rte_cpu_get_features(hwcap_registers_t out)
+{
+ out[REG_HWCAP] = rte_cpu_getauxval(AT_HWCAP);
+}
+
+/*
+ * Checks if a particular flag is available on current machine.
+ */
+int
+rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
+{
+ const struct feature_entry *feat;
+ hwcap_registers_t regs = {0};
+
+ if (feature >= RTE_CPUFLAG_NUMFLAGS)
+ return -ENOENT;
+
+ feat = &rte_cpu_feature_table[feature];
+ if (feat->reg == REG_NONE)
+ return -EFAULT;
+
+ rte_cpu_get_features(regs);
+ return (regs[feat->reg] >> feat->bit) & 1;
+}
+
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+ if (feature >= RTE_CPUFLAG_NUMFLAGS)
+ return NULL;
+ return rte_cpu_feature_table[feature].name;
+}
+
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
+{
+ memset(intrinsics, 0, sizeof(*intrinsics));
+}
new file mode 100644
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#include "eal_private.h"
+
+#define LOONGARCH_CPUCFG4 0x4
+#define CPUCFG4_CCFREQ_MASK 0xFFFFFFFF
+#define CPUCFG4_CCFREQ_SHIFT 0
+
+#define LOONGARCH_CPUCFG5 0x5
+#define CPUCFG5_CCMUL_MASK 0xFFFF
+#define CPUCFG5_CCMUL_SHIFT 0
+
+#define CPUCFG5_CCDIV_MASK 0xFFFF0000
+#define CPUCFG5_CCDIV_SHIFT 16
+
+static __rte_noinline uint32_t
+read_cpucfg(int arg)
+{
+ int ret = 0;
+
+ __asm__ __volatile__ (
+ "cpucfg %[var], %[index]\n"
+ : [var]"=r"(ret)
+ : [index]"r"(arg)
+ :
+ );
+
+ return ret;
+}
+
+uint64_t
+get_tsc_freq_arch(void)
+{
+ uint32_t base_freq, mul_factor, div_factor;
+
+ base_freq = read_cpucfg(LOONGARCH_CPUCFG4);
+ mul_factor = (read_cpucfg(LOONGARCH_CPUCFG5) & CPUCFG5_CCMUL_MASK) >>
+ CPUCFG5_CCMUL_SHIFT;
+ div_factor = (read_cpucfg(LOONGARCH_CPUCFG5) & CPUCFG5_CCDIV_MASK) >>
+ CPUCFG5_CCDIV_SHIFT;
+
+ return base_freq * mul_factor / div_factor;
+}
new file mode 100644
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#include "rte_hypervisor.h"
+
+enum rte_hypervisor
+rte_hypervisor_get(void)
+{
+ return RTE_HYPERVISOR_UNKNOWN;
+}
new file mode 100644
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Loongson Technology Corporation Limited
+ */
+
+#include "rte_power_intrinsics.h"
+
+/**
+ * This function is not supported on LOONGARCH.
+ */
+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 LOONGARCH.
+ */
+int
+rte_power_pause(const uint64_t tsc_timestamp)
+{
+ RTE_SET_USED(tsc_timestamp);
+
+ return -ENOTSUP;
+}
+
+/**
+ * This function is not supported on LOONGARCH.
+ */
+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;
+}
@@ -56,6 +56,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('loongarch')
+ arch_subdir = 'loongarch'
endif
# configure the build, and make sure configs here and in config folder are