eal/loongarch: support LoongArch architecture

Add all necessary elements for DPDK to compile and run EAL on
LoongArch64 Soc.

This includes:

- EAL library implementation for LoongArch ISA.
- meson build structure for 'loongarch' architecture.
  RTE_ARCH_LOONGARCH define is added for architecture identification.
- xmm_t structure operation stubs as there is no vector support in
  the current version for LoongArch.

Compilation was tested on Debian and CentOS using loongarch64
cross-compile toolchain from x86 build hosts. Functions were tested
on Loongnix and Kylin which are two Linux distributions supported
LoongArch host based on Linux 4.19 maintained by Loongson
Corporation.

We also tested DPDK on LoongArch with some external applications,
including: Pktgen-DPDK, OVS, VPP.

The platform is currently marked as linux-only because there is no
other OS than Linux support LoongArch host currently.

The i40e PMD driver is disabled on LoongArch because of the absence
of vector support in the current version.

Similar to RISC-V, the compilation of following modules has been
disabled by this commit and will be re-enabled in later commits as
fixes are introduced:
net/ixgbe, net/memif, net/tap, example/l3fwd.

Signed-off-by: Min Zhou <zhoumin@loongson.cn>
This commit is contained in:
Min Zhou 2022-10-04 23:40:42 +08:00 committed by David Marchand
parent 285ca8e1fd
commit 29631ee5c8
36 changed files with 976 additions and 1 deletions

View File

@ -294,6 +294,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/

View File

@ -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_ */

View File

@ -0,0 +1,16 @@
[binaries]
c = ['ccache', 'loongarch64-unknown-linux-gnu-gcc']
cpp = ['ccache', 'loongarch64-unknown-linux-gnu-g++']
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'

View File

@ -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)

View File

@ -260,6 +260,10 @@ build build-x86-mingw $f skipABI -Dexamples=helloworld
f=$srcdir/config/arm/arm64_armv8_linux_gcc
build build-arm64-generic-gcc $f ABI $use_shared
# generic LoongArch
f=$srcdir/config/loongarch/loongarch_loongarch64_linux_gcc
build build-loongarch64-generic-gcc $f ABI $use_shared
# IBM POWER
f=$srcdir/config/ppc/ppc64le-power8-linux-gcc
build build-ppc64-power8-gcc $f ABI $use_shared

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,95 @@
.. 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 a precompiled toolchain:
* 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.
After downloading the archive, we need to unzip and add those executable
binaries into the PATH as follows:
.. code-block:: console
tar -xvf <download_dir>/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
Generate the cross toolchain from sources
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively the toolchain may be built straight from upstream sources.
You can refer to this thread `Introduce support for LoongArch architecture
<https://inbox.dpdk.org/dev/53b50799-cb29-7ee6-be89-4fe21566e127@loongson.cn/T/#m1da99578f85894a4ddcd8e39d8239869e6a501d1>`_.
Before you start running the script, you may need to install some dependencies.
For instance, if you want to run this script in a RHEL 8 system, you can use
the following command to install these dependencies:
.. code-block:: console
subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms
dnf install bison diffutils file flex gcc gcc-c++ git gmp-devel libtool make python3 rsync texinfo wget xz zlib-devel ccache
Once generated, the location of the executable binaries must be added to PATH:
.. code-block:: console
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.

View File

@ -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

View File

@ -832,6 +832,14 @@ ARMv8
Support armv8a (64bit) architecture.
.. _nic_features_loongarch64:
LoongArch64
-----------
Support 64-bit LoongArch architecture.
.. _nic_features_power8:
Power8

View File

@ -71,6 +71,7 @@ Linux =
Windows =
ARMv7 =
ARMv8 =
LoongArch64 =
Power8 =
rv64 =
x86-32 =

View File

@ -55,6 +55,14 @@ 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.
* **Added configuration for asynchronous flow connection tracking.**
Added connection tracking action number hint to ``rte_flow_configure``

View File

@ -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
if arch_subdir == 'riscv'
build = false
reason = 'not supported on RISC-V'

View File

@ -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')

View File

@ -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'

View File

@ -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'

View File

@ -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(

View File

@ -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
}
/*

View File

@ -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'))

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 /* RTE_VECT_LOONGARCH_H */

View File

@ -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',
)

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2022 Loongson Technology Corporation Limited
*/
#include <errno.h>
#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;
}

View File

@ -52,6 +52,8 @@ if host_machine.cpu_family().startswith('x86')
arch_subdir = 'x86'
elif host_machine.cpu_family().startswith('arm') or host_machine.cpu_family().startswith('aarch')
arch_subdir = 'arm'
elif host_machine.cpu_family().startswith('loongarch')
arch_subdir = 'loongarch'
elif host_machine.cpu_family().startswith('ppc')
arch_subdir = 'ppc'
elif host_machine.cpu_family().startswith('riscv')