From ebde2f369810b61288ca5c115f2c38f074300661 Mon Sep 17 00:00:00 2001 From: robert Date: Thu, 11 Jul 2024 16:06:33 +0200 Subject: [PATCH 1/9] fix(oran_fhlib_5g): Build error due to SIMDE header for Neon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove include of SIMDE Neon header sse_intrinsic.h to compile on ARM. Otherwise the error below is issued. ``` /usr/include/simde/arm/neon/get_lane.h:279:5: error: incompatible type for argument 1 of ‘vget_lane_f16’ 279 | SIMDE_CONSTIFY_8_(vget_lane_f16, r, (HEDLEY_UNREACHABLE(), SIMDE_FLOAT16_VALUE(0.0)), lane, v); removed the inclusion of neon.h ``` --- openair1/PHY/sse_intrin.h | 1 - 1 file changed, 1 deletion(-) diff --git a/openair1/PHY/sse_intrin.h b/openair1/PHY/sse_intrin.h index d6c3157ce8..25337d557a 100644 --- a/openair1/PHY/sse_intrin.h +++ b/openair1/PHY/sse_intrin.h @@ -65,7 +65,6 @@ // /usr/lib/gcc/x86_64-redhat-linux/8/include/gfniintrin.h:57:1: error: inlining failed in call to always_inline ‘_mm_gf2p8affine_epi64_epi8’: target specific option mismatch #include -#include #endif // x86_64 || i386 #include #include "assertions.h" From a0f16e7e83f8d3cf3928ad118b4999ad22cd5b08 Mon Sep 17 00:00:00 2001 From: brobert Date: Sat, 27 Jul 2024 11:53:03 +0200 Subject: [PATCH 2/9] fix(oran_fhlib_5g): Do not include immintrin.h for Arm targets Remove include of immintrin.h in radio/fhi_72/oaioran.c when compiling for a Arm target. --- radio/fhi_72/oaioran.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index cbc530a785..afa6384741 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -25,8 +25,11 @@ #include "xran_fh_o_du.h" #include "xran_compression.h" +#if defined(__arm__) || defined(__aarch64__) +#else // xran_cp_api.h uses SIMD, but does not include it #include +#endif #include "xran_cp_api.h" #include "xran_sync_api.h" #include "oran_isolate.h" From db27b09b7cfb2bc1b3da88c4d6ebbf6eeb5a5388 Mon Sep 17 00:00:00 2001 From: brobert Date: Mon, 29 Jul 2024 10:00:34 +0200 Subject: [PATCH 3/9] enabling ARM and INTEL memory alignment --- radio/fhi_72/oran-init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index fd3fdaa5bf..38e766805a 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -306,7 +306,14 @@ static void oran_allocate_buffers(void *handle, uint32_t xran_max_antenna_nr = RTE_MAX(fh_config->neAxc, fh_config->neAxcUl); uint32_t xran_max_sections_per_slot = RTE_MAX(fh_config->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT); - pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256); +#if defined(__arm__) || defined(__aarch64__) + // ARM-specific memory allocation + int ret = posix_memalign((void**)&pi->buf_list, 256, sizeof(*pi->buf_list)); + AssertFatal(ret == 0, "out of memory\n"); +#else + // Intel-specific memory allocation + pi->buf_list = _mm_malloc(sizeof(*pi->buf_list), 256); +#endif AssertFatal(pi->buf_list != NULL, "out of memory\n"); oran_buf_list_t *bl = pi->buf_list; From 047e80f070e567674d233831cdc3e8b0d69def5d Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 27 Mar 2025 15:09:59 +0000 Subject: [PATCH 4/9] feat(oran_fhlib_5g): Make E release patch dual Update the xran E release patch to work for Arm targets in addition to x86 targets. Co-authored-by: Yi-Hung Chang Co-authored-by: brobert --- .../E/oaioran_E.patch | 872 +++++++++++++++++- radio/fhi_72/CMakeLists.txt | 4 +- 2 files changed, 838 insertions(+), 38 deletions(-) diff --git a/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch b/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch index e1915cd996..baa5378673 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/E/oaioran_E.patch @@ -7,20 +7,24 @@ index 7508117..ce17ebd 100644 #include -#define VERSIONX "oran_e_maintenance_release_v1.0" -+#define VERSIONX "oran_e_maintenance_release_v1.4" ++#define VERSIONX "oran_e_maintenance_release_v1.5" #define APP_O_DU 0 #define APP_O_RU 1 diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile -index de141bf..c12b912 100644 +index de141bf..fa2923f 100644 --- a/fhi_lib/lib/Makefile +++ b/fhi_lib/lib/Makefile -@@ -23,11 +23,11 @@ MYCUSTOMSPACE1='------------------------------------------------------------' +@@ -23,12 +23,25 @@ MYCUSTOMSPACE1='------------------------------------------------------------' ############################################################## # Tools configuration ############################################################## -CC := icc -CPP := icpc ++# Default target architecture and compiler ++TARGET ?= x86 ++# Architecture and compiler-specific tools and flags ++ifeq ($(TARGET), x86) +CC := gcc +CPP := g++ AS := as @@ -28,53 +32,99 @@ index de141bf..c12b912 100644 -LD := icc +LD := gcc OBJDUMP := objdump ++else ifeq ($(TARGET), armv8) # aarch64 ++CC := gcc ++CPP := g++ ++LD := gcc ++CFLAGS += -march=armv8-a ++LDFLAGS += ++else ++ $(error Unsupported target architecture: $(TARGET)) ++endif ifeq ($(SHELL),cmd.exe) -@@ -57,7 +57,7 @@ endif + MD := mkdir.exe -p +@@ -57,7 +70,11 @@ endif RTE_TARGET ?= x86_64-native-linux-icc -RTE_INC := $(shell PKG_CONFIG_PATH=/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) ++ifeq ($(TARGET), x86) +RTE_INC := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH):/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) ++else ifeq ($(TARGET), armv8) ++RTE_INC := $(pkgconf --cflags-only-I libdpdk) ++endif API_DIR := $(PROJECT_DIR)/api SRC_DIR := $(PROJECT_DIR)/src ETH_DIR := $(PROJECT_DIR)/ethernet -@@ -95,8 +95,7 @@ CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ +@@ -88,6 +105,7 @@ CC_SRC = $(ETH_DIR)/ethdi.c \ + $(SRC_DIR)/xran_main.c \ + $(SRC_DIR)/xran_delay_measurement.c + ++ifeq ($(TARGET), x86) + CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ + $(SRC_DIR)/xran_bfp_ref.cpp \ + $(SRC_DIR)/xran_bfp_cplane8.cpp \ +@@ -95,15 +113,17 @@ CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ $(SRC_DIR)/xran_bfp_cplane32.cpp \ $(SRC_DIR)/xran_bfp_cplane64.cpp \ $(SRC_DIR)/xran_bfp_uplane_9b16rb.cpp \ - $(SRC_DIR)/xran_bfp_uplane.cpp \ - $(SRC_DIR)/xran_mod_compression.cpp + $(SRC_DIR)/xran_bfp_uplane.cpp ++endif ++ifeq ($(TARGET), x86) CPP_SRC_SNC = $(SRC_DIR)/xran_compression_snc.cpp \ $(SRC_DIR)/xran_bfp_cplane8_snc.cpp \ -@@ -112,12 +111,12 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ + $(SRC_DIR)/xran_bfp_cplane16_snc.cpp \ + $(SRC_DIR)/xran_bfp_cplane32_snc.cpp \ + $(SRC_DIR)/xran_bfp_cplane64_snc.cpp \ + $(SRC_DIR)/xran_bfp_uplane_snc.cpp ++endif + + CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ + -fdata-sections \ +@@ -112,12 +132,21 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ -fPIC \ -Wall \ -Wimplicit-function-declaration \ - -g -O3 -wd1786 -mcmodel=large -+ -g -O -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512#--wd1786 -mcmodel=large ++ -g -O -CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \ - -no-prec-div -fp-model fast=2 -fPIC \ - -no-prec-sqrt -falign-functions=16 -fast-transcendentals \ - -Werror -Wno-unused-variable -std=c++14 -mcmodel=large ++ifeq ($(TARGET), x86) ++CC_FLAGS += -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512#--wd1786 -mcmodel=large ++endif ++ ++ifeq ($(TARGET), x86) +CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \ + -fPIC \ + -falign-functions=16 \ + -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512 ++else ifeq ($(TARGET), armv8) ++CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \ ++ -Werror -Wno-unused-variable -std=c++14 ++endif INC := -I$(API_DIR) -I$(ETH_DIR) -I$(SRC_DIR) -I$(RTE_INC) DEF := -@@ -150,8 +149,8 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) +@@ -150,8 +179,13 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS)) #-qopt-report=5 -qopt-matmul -qopt-report-phase=all -CPP_COMP := -O3 -DNDEBUG -xcore-avx512 -fPIE -restrict -fasm-blocks -CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE -restrict -fasm-blocks ++ifeq ($(TARGET), x86) +CPP_COMP := -O3 -DNDEBUG -fPIE +CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE ++else ifeq ($(TARGET), armv8) ++CPP_COMP := -O3 -DNDEBUG -fPIE -Wrestrict ++CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE -Wrestrict ++endif CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF) CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF) CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF) @@ -113,6 +163,36 @@ index 7419ae1..a85f973 100644 /** * @ingroup xran * +diff --git a/fhi_lib/lib/api/xran_pkt_cp.h b/fhi_lib/lib/api/xran_pkt_cp.h +index 531c51f..bcb6541 100644 +--- a/fhi_lib/lib/api/xran_pkt_cp.h ++++ b/fhi_lib/lib/api/xran_pkt_cp.h +@@ -33,6 +33,14 @@ + extern "C" { + #endif + ++#include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++typedef int32x4_t simd_data_t; ++#else ++#include ++typedef __m128i simd_data_t; ++#endif + + /********************************************************************** + * Common structures for C/U-plane +@@ -255,8 +263,8 @@ union xran_cp_radioapp_section_ext3_first { + uint64_t reserved2:16; + }all_bits; + +- struct{ +- __m128i data_field1; ++ struct { ++ simd_data_t data_field1; + }data_field; + } __attribute__((__packed__)); + diff --git a/fhi_lib/lib/api/xran_up_api.h b/fhi_lib/lib/api/xran_up_api.h index 7d3afc5..e2f1f21 100644 --- a/fhi_lib/lib/api/xran_up_api.h @@ -136,10 +216,21 @@ index 7d3afc5..e2f1f21 100644 inline int xran_prepare_iq_symbol_portion( struct rte_mbuf *mbuf, diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c -index b6ba257..1618f65 100644 +index b6ba257..07b7a38 100644 --- a/fhi_lib/lib/ethernet/ethdi.c +++ b/fhi_lib/lib/ethernet/ethdi.c -@@ -326,8 +326,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -37,7 +37,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +@@ -326,8 +329,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, char bbdev_wdev[32] = ""; char bbdev_vdev[32] = ""; char iova_mode[32] = "--iova-mode=pa"; @@ -150,7 +241,7 @@ index b6ba257..1618f65 100644 char ring_name[32] = ""; int32_t xran_port = -1; portid_t port_id; -@@ -335,6 +335,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -335,6 +338,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, uint16_t count; char *argv[] = { name, core_mask, "-n2", iova_mode, socket_mem, socket_limit, "--proc-type=auto", @@ -158,7 +249,7 @@ index b6ba257..1618f65 100644 "--file-prefix", name, "-a0000:00:00.0", bbdev_wdev, bbdev_vdev}; -@@ -479,11 +480,13 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -479,11 +483,13 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, ctx->tx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING_TRX, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); PANIC_ON(ctx->tx_ring[i] == NULL, "failed to allocate rx ring"); @@ -172,7 +263,7 @@ index b6ba257..1618f65 100644 } } } else { -@@ -553,7 +556,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -553,7 +559,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, ctx->up_dl_pkt_gen_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), /*RING_F_SC_DEQ*/0); PANIC_ON(ctx->up_dl_pkt_gen_ring[i] == NULL, "failed to allocate dl gen ring"); @@ -181,6 +272,36 @@ index b6ba257..1618f65 100644 } return 1; +diff --git a/fhi_lib/lib/ethernet/ethernet.c b/fhi_lib/lib/ethernet/ethernet.c +index 0930665..80e2e10 100644 +--- a/fhi_lib/lib/ethernet/ethernet.c ++++ b/fhi_lib/lib/ethernet/ethernet.c +@@ -37,7 +37,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +diff --git a/fhi_lib/lib/src/xran_app_frag.c b/fhi_lib/lib/src/xran_app_frag.c +index cb526ee..90b2860 100644 +--- a/fhi_lib/lib/src/xran_app_frag.c ++++ b/fhi_lib/lib/src/xran_app_frag.c +@@ -27,7 +27,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include diff --git a/fhi_lib/lib/src/xran_bfp_ref.cpp b/fhi_lib/lib/src/xran_bfp_ref.cpp index e6d3067..8e0abee 100644 --- a/fhi_lib/lib/src/xran_bfp_ref.cpp @@ -224,11 +345,37 @@ index a345df4..2a94e01 100644 /// Store exponent first dataOut->dataCompressed[thisRBExpAddr] = thisExp; /// Now have 1 RB worth of bytes separated into 3 chunks (1 per lane) +diff --git a/fhi_lib/lib/src/xran_cb_proc.c b/fhi_lib/lib/src/xran_cb_proc.c +index b35d55c..2e7ec05 100644 +--- a/fhi_lib/lib/src/xran_cb_proc.c ++++ b/fhi_lib/lib/src/xran_cb_proc.c +@@ -25,7 +25,10 @@ + + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c -index baa673f..00bfdf2 100644 +index baa673f..7bdc475 100644 --- a/fhi_lib/lib/src/xran_common.c +++ b/fhi_lib/lib/src/xran_common.c -@@ -650,12 +650,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -31,7 +31,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + + #include "xran_common.h" +@@ -650,12 +653,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) uint8_t compMeth = 0; uint8_t iqWidth = 0; @@ -244,7 +391,7 @@ index baa673f..00bfdf2 100644 if (staticComp == XRAN_COMP_HDR_TYPE_STATIC) { -@@ -674,6 +677,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -674,6 +680,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) &subframe_id, &slot_id, &symb_id, @@ -252,7 +399,7 @@ index baa673f..00bfdf2 100644 &seq, &num_prbu, &start_prbu, -@@ -683,28 +687,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -683,28 +690,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) expect_comp, staticComp, &compMeth, @@ -286,7 +433,7 @@ index baa673f..00bfdf2 100644 #ifndef FCN_ADAPT if(valid_res != 0) { print_dbg("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes); -@@ -756,7 +747,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -756,7 +750,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) print_dbg("Transport layer fragmentation (eCPRI) is not supported\n"); } @@ -295,7 +442,7 @@ index baa673f..00bfdf2 100644 /* PRACH packet has ruportid = num_eAxc + ant_id */ Ant_ID -= p_dev_ctx->PrachCPConfig.eAxC_offset; symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes; -@@ -1189,7 +1180,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc +@@ -1189,7 +1183,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc timeOffset += startSymId * (2048 + 144); } timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu @@ -304,7 +451,7 @@ index baa673f..00bfdf2 100644 timeOffset += 16; params->dir = XRAN_DIR_UL; -@@ -1295,8 +1286,7 @@ int32_t ring_processing_func(void* args) +@@ -1295,8 +1289,7 @@ int32_t ring_processing_func(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){ for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) { @@ -367,11 +514,159 @@ index 112caae..7c74342 100644 return xranlib_decompress_avxsnc_bfw(request,response); } else { return xranlib_decompress_avx512_bfw(request,response); +diff --git a/fhi_lib/lib/src/xran_cp_api.c b/fhi_lib/lib/src/xran_cp_api.c +index 02ba81c..74ef600 100644 +--- a/fhi_lib/lib/src/xran_cp_api.c ++++ b/fhi_lib/lib/src/xran_cp_api.c +@@ -25,7 +25,11 @@ + * @author Intel Corporation + * + **/ ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + #include + #include + +@@ -821,7 +825,11 @@ xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *p + | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId) + | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers); + data_fourth_byte = params->beamIdAP1; ++#if defined(__arm__) || defined(__aarch64__) ++ ext3_f->data_field.data_field1 = (int32x4_t){data_first_byte, data_second_byte, data_third_byte, data_fourth_byte}; ++#else + ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte); ++#endif + + /* convert byte order */ + tmp = (uint64_t *)ext3_f; +diff --git a/fhi_lib/lib/src/xran_cp_proc.c b/fhi_lib/lib/src/xran_cp_proc.c +index e40ce72..b2c6ea6 100644 +--- a/fhi_lib/lib/src/xran_cp_proc.c ++++ b/fhi_lib/lib/src/xran_cp_proc.c +@@ -35,7 +35,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + + #include + #include +diff --git a/fhi_lib/lib/src/xran_delay_measurement.c b/fhi_lib/lib/src/xran_delay_measurement.c +index 931aceb..a3b53fc 100644 +--- a/fhi_lib/lib/src/xran_delay_measurement.c ++++ b/fhi_lib/lib/src/xran_delay_measurement.c +@@ -23,7 +23,10 @@ + * @author Intel Corporation + **/ + #define _GNU_SOURCE ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +diff --git a/fhi_lib/lib/src/xran_dev.c b/fhi_lib/lib/src/xran_dev.c +index fef64c8..612445d 100644 +--- a/fhi_lib/lib/src/xran_dev.c ++++ b/fhi_lib/lib/src/xran_dev.c +@@ -35,7 +35,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +@@ -55,6 +58,27 @@ + + static struct xran_device_ctx *g_xran_dev_ctx[XRAN_PORTS_NUM] = {NULL, NULL, NULL, NULL}; + ++struct xran_device_ctx *allocate_device_ctx(size_t xran_ports_num, size_t alignment) { ++ void *ptr = NULL; ++ ++#if defined(__arm__) || defined(__aarch64__) ++ // ARM-specific memory allocation ++ if (posix_memalign(&ptr, alignment, sizeof(struct xran_device_ctx) * xran_ports_num) != 0) { ++ print_err("posix_memalign: pCtx allocation error\n"); ++ return NULL; ++ } ++#else ++ // Intel-specific memory allocation ++ ptr = _mm_malloc(sizeof(struct xran_device_ctx) * xran_ports_num, alignment); ++ if (ptr == NULL) { ++ print_err("_mm_malloc: pCtx allocation error\n"); ++ return NULL; ++ } ++#endif ++ ++ return (struct xran_device_ctx *)ptr; ++} ++ + int32_t + xran_dev_create_ctx(uint32_t xran_ports_num) + { +@@ -64,7 +88,7 @@ xran_dev_create_ctx(uint32_t xran_ports_num) + if (xran_ports_num > XRAN_PORTS_NUM) + return -1; + +- pCtx = (struct xran_device_ctx *) _mm_malloc(sizeof(struct xran_device_ctx)*xran_ports_num, 64); ++ pCtx = allocate_device_ctx(xran_ports_num, 64); + if(pCtx){ + for(i = 0; i < xran_ports_num; i++){ + g_xran_dev_ctx[i] = pCtx; diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c -index 89dcc1f..640f6b6 100644 +index 89dcc1f..ded4116 100644 --- a/fhi_lib/lib/src/xran_main.c +++ b/fhi_lib/lib/src/xran_main.c -@@ -272,7 +272,7 @@ xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_de +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include +@@ -102,6 +106,25 @@ void tti_to_phy_cb(struct rte_timer *tim, void *arg); + + int32_t xran_pkt_gen_process_ring(struct rte_ring *r); + ++void *mm_allocate_handle(size_t size, size_t alignment) { ++ void *ptr = NULL; ++#if defined(__arm__) || defined(__aarch64__) ++ // ARM-specific memory allocation ++ if (posix_memalign(&ptr, alignment, size) != 0) { ++ fprintf(stderr, "posix_memalign: allocation error\n"); ++ return NULL; ++ } ++#else ++ // Intel-specific memory allocation ++ ptr = _mm_malloc(size, alignment); ++ if (ptr == NULL) { ++ fprintf(stderr, "_mm_malloc: allocation error\n"); ++ return NULL; ++ } ++#endif ++ return ptr; ++} ++ + void + xran_updateSfnSecStart(void) + { +@@ -272,7 +295,7 @@ xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_de printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]); } @@ -380,7 +675,7 @@ index 89dcc1f..640f6b6 100644 print_dbg("PRACH eAxC_offset %d\n", pPrachCPConfig->eAxC_offset); /* Save some configs for app */ -@@ -844,7 +844,7 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg) +@@ -844,7 +867,7 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg) struct xran_cp_gen_params params; struct xran_section_gen_info sect_geninfo[8]; struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc(); @@ -389,7 +684,7 @@ index 89dcc1f..640f6b6 100644 /* start new section information list */ xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, ctx_id); -@@ -1059,6 +1059,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1059,6 +1082,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru { case ECPRI_IQ_DATA: pkt_data[num_data++] = pkt; @@ -397,7 +692,7 @@ index 89dcc1f..640f6b6 100644 break; // For RU emulation case ECPRI_RT_CONTROL_DATA: -@@ -1076,7 +1077,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1076,7 +1100,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru break; default: if (p_dev_ctx->fh_init.io_cfg.id == O_DU) { @@ -406,7 +701,17 @@ index 89dcc1f..640f6b6 100644 } break; } -@@ -1771,8 +1772,7 @@ ring_processing_func_per_port(void* args) +@@ -1366,8 +1390,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI + for (i = 0; i < nNumInstances; i++) { + + /* Allocate Memory for CC handles */ +- pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64); +- ++ pCcHandle = (XranSectorHandleInfo *)mm_allocate_handle(/*"xran_cc_handles",*/ sizeof(XranSectorHandleInfo), 64); + if(pCcHandle == NULL) + return XRAN_STATUS_RESOURCE; + +@@ -1771,8 +1794,7 @@ ring_processing_func_per_port(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) { if (ctx->vf2xran_port[i] == port_id) { for(qi = 0; qi < ctx->rxq_per_port[port_id]; qi++){ @@ -416,7 +721,7 @@ index 89dcc1f..640f6b6 100644 } } } -@@ -1837,8 +1837,6 @@ xran_spawn_workers(void) +@@ -1837,8 +1859,6 @@ xran_spawn_workers(void) nWorkerCore = nWorkerCore << 1; } @@ -425,7 +730,385 @@ index 89dcc1f..640f6b6 100644 printf("O-XU %d\n", eth_ctx->io_cfg.id); printf("HW %d\n", icx_cpu); -@@ -3074,6 +3072,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, +@@ -1876,7 +1896,7 @@ xran_spawn_workers(void) + eth_ctx->time_wrk_cfg.arg = NULL; + eth_ctx->time_wrk_cfg.state = 1; + +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -1898,7 +1918,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -1925,7 +1945,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -1956,7 +1976,7 @@ xran_spawn_workers(void) + + p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; + +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -1979,7 +1999,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2006,7 +2026,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2033,7 +2053,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2048,7 +2068,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2063,7 +2083,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2102,7 +2122,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2117,7 +2137,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2132,7 +2152,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2147,7 +2167,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2186,7 +2206,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2201,7 +2221,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 Eth Tx **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); +@@ -2217,7 +2237,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2232,7 +2252,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2247,7 +2267,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 4 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2281,7 +2301,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 Eth RX */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2296,7 +2316,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2311,7 +2331,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2326,7 +2346,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2341,7 +2361,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** FH TX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2379,7 +2399,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2406,7 +2426,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2433,7 +2453,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2448,7 +2468,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2463,7 +2483,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2501,7 +2521,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2516,7 +2536,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2531,7 +2551,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2546,7 +2566,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2569,7 +2589,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2584,7 +2604,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2599,7 +2619,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2614,7 +2634,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2629,7 +2649,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 4 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2651,7 +2671,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 Eth RX */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2666,7 +2686,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2681,7 +2701,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2696,7 +2716,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2711,7 +2731,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** FH TX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx *)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3074,6 +3094,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, return tti; } @@ -450,6 +1133,22 @@ index 89dcc1f..640f6b6 100644 int32_t xran_set_debug_stop(int32_t value, int32_t count) { +diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c +index 3e401e6..566490d 100644 +--- a/fhi_lib/lib/src/xran_mem_mgr.c ++++ b/fhi_lib/lib/src/xran_mem_mgr.c +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include diff --git a/fhi_lib/lib/src/xran_mod_compression.cpp b/fhi_lib/lib/src/xran_mod_compression.cpp index 7d4a5d0..87bdbd5 100644 --- a/fhi_lib/lib/src/xran_mod_compression.cpp @@ -469,10 +1168,22 @@ index 7d4a5d0..87bdbd5 100644 } diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c -index 36bd72c..f7f5678 100644 +index 36bd72c..4d57898 100644 --- a/fhi_lib/lib/src/xran_rx_proc.c +++ b/fhi_lib/lib/src/xran_rx_proc.c -@@ -107,6 +107,10 @@ int xran_process_prach_sym(void *arg, +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include +@@ -107,6 +111,10 @@ int xran_process_prach_sym(void *arg, if(mb) rte_pktmbuf_free(mb); @@ -483,11 +1194,100 @@ index 36bd72c..f7f5678 100644 if(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) { int idx = 0; uint16_t *psrc = (uint16_t *)iq_data_start; +diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c +index b13101a..6d46298 100644 +--- a/fhi_lib/lib/src/xran_timer.c ++++ b/fhi_lib/lib/src/xran_timer.c +@@ -29,7 +29,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + #include "xran_timer.h" + #include "xran_printf.h" + #include "xran_mlog_lnx.h" +@@ -141,12 +145,30 @@ void timing_adjust_gps_second(struct timespec* p_time) + + return; + } ++#if defined(__x86_64__) + uint64_t xran_tick(void) + { + uint32_t hi, lo; + __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 ); + } ++#elif defined(__aarch64__) ++#include ++uint64_t xran_tick(void) { ++ struct timeval tv; ++ gettimeofday(&tv, NULL); ++ return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec; ++} ++#elif defined(__arm__) ++#include ++uint64_t xran_tick(void) { ++ struct timespec ts; ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ return (uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec; ++} ++#else ++#error "Unsupported architecture" ++#endif + + unsigned long get_ticks_diff(unsigned long curr_tick, unsigned long last_tick) + { +diff --git a/fhi_lib/lib/src/xran_transport.c b/fhi_lib/lib/src/xran_transport.c +index 881f6f6..dbea6a8 100644 +--- a/fhi_lib/lib/src/xran_transport.c ++++ b/fhi_lib/lib/src/xran_transport.c +@@ -27,7 +27,10 @@ + + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + +diff --git a/fhi_lib/lib/src/xran_tx_proc.c b/fhi_lib/lib/src/xran_tx_proc.c +index 3cfb2be..eb02195 100644 +--- a/fhi_lib/lib/src/xran_tx_proc.c ++++ b/fhi_lib/lib/src/xran_tx_proc.c +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c -index 397853a..8977e3d 100644 +index 397853a..14266de 100644 --- a/fhi_lib/lib/src/xran_up_api.c +++ b/fhi_lib/lib/src/xran_up_api.c -@@ -329,6 +329,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -25,7 +25,10 @@ + * + **/ + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + + #include "xran_fh_o_du.h" +@@ -329,6 +332,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, uint8_t *subframe_id, uint8_t *slot_id, uint8_t *symb_id, @@ -495,7 +1295,7 @@ index 397853a..8977e3d 100644 union ecpri_seq_id *seq_id, uint16_t *num_prbu, uint16_t *start_prbu, -@@ -338,7 +339,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -338,7 +342,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, int8_t expect_comp, enum xran_comp_hdr_type staticComp, uint8_t *compMeth, @@ -505,7 +1305,7 @@ index 397853a..8977e3d 100644 { #if XRAN_MLOG_VAR uint32_t mlogVar[10]; -@@ -374,6 +376,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -374,6 +379,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, return 0; /* packet too short */ radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value); @@ -514,7 +1314,7 @@ index 397853a..8977e3d 100644 if (frame_id) *frame_id = radio_hdr->frame_id; -@@ -387,6 +391,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -387,6 +394,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, if (symb_id) *symb_id = radio_hdr->sf_slot_sym.symb_id; @@ -523,7 +1323,7 @@ index 397853a..8977e3d 100644 /* Process data section hdr */ struct data_section_hdr *data_hdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr)); -@@ -401,6 +407,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -401,6 +410,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, *sym_inc = data_hdr->fields.sym_inc; *rb = data_hdr->fields.rb; *sect_id = data_hdr->fields.sect_id; diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index 8b047a9316..4a9064e661 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -17,12 +17,12 @@ add_library(oran_fhlib_5g MODULE ) find_package(xran REQUIRED) -if(xran_VERSION VERSION_EQUAL 5.1.4) +if(xran_VERSION VERSION_EQUAL 5.1.5) target_compile_definitions(oran_fhlib_5g PRIVATE E_RELEASE) elseif(xran_VERSION VERSION_EQUAL 6.1.1) target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE) else() - message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.4 (E release) or 6.1.1 (F release)") + message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.5 (E release) or 6.1.1 (F release)") endif() # Ignore xran-specific warning: we don't care/can't change the following warning, so suppress From 54fd8ed9df804712ad1ab989290914456d94e7ba Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Tue, 18 Mar 2025 10:05:09 +0000 Subject: [PATCH 5/9] feat(oran_fhlib_5g): BFP compression and decompression for Arm targets The fronthaul library ships with BFP compression for AVX512 enabled targets. This commit adds BFP compression for Arm targets by using the ArmRAL library. --- cmake_targets/tools/MODULES/Findarmral.cmake | 123 +++++++++++++++++++ radio/fhi_72/CMakeLists.txt | 5 + radio/fhi_72/armral_bfp_compression.c | 116 +++++++++++++++++ radio/fhi_72/armral_bfp_compression.h | 59 +++++++++ radio/fhi_72/oaioran.c | 33 ++++- 5 files changed, 330 insertions(+), 6 deletions(-) create mode 100644 cmake_targets/tools/MODULES/Findarmral.cmake create mode 100644 radio/fhi_72/armral_bfp_compression.c create mode 100644 radio/fhi_72/armral_bfp_compression.h diff --git a/cmake_targets/tools/MODULES/Findarmral.cmake b/cmake_targets/tools/MODULES/Findarmral.cmake new file mode 100644 index 0000000000..79407ffc91 --- /dev/null +++ b/cmake_targets/tools/MODULES/Findarmral.cmake @@ -0,0 +1,123 @@ +# +# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The OpenAirInterface Software Alliance licenses this file to You under +# the OAI Public License, Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.openairinterface.org/?page_id=698 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ +# For more information about the OpenAirInterface (OAI) Software Alliance: +# contact@openairinterface.org +# + +# FindArmral +# ------- +# +# Finds the armral library. +# the version is currently hardcoded to 25.01 +# +# Optional options +# ^^^^^^^^^^^^^^^^ +# +# ``armral_LOCATION`` +# The location of the library. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# +# This module provides the following imported targets, if found: +# +# ``armral`` +# The armral library +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This will define the following variables: +# +# ``armral_FOUND`` +# True if the system has the armral library. +# ``armral_VERSION`` +# The version of the armral library which was found. +# ``armral_INCLUDE_DIRS`` +# Include directories needed to use armral. +# ``armral_LIBRARIES`` +# Libraries needed to link to armral. +# +# Cache Variables +# ^^^^^^^^^^^^^^^ +# +# The following cache variables may also be set: +# +# ``armral_INCLUDE_DIR`` +# The directory containing ``armral.h``. +# ``armral_LIBRARY`` +# The path to the armral library. + +option(armral_LOCATION "directory of ArmRAL library" "") +if (NOT armral_LOCATION) + set(armral_LOCATION "/usr/local") +endif() +if (NOT EXISTS ${armral_LOCATION}) + message(FATAL_ERROR "no such directory: ${armral_LOCATION}") +endif() + +find_path(armral_INCLUDE_DIR + NAMES + armral.h + HINTS ${armral_LOCATION} + PATH_SUFFIXES include + NO_DEFAULT_PATH +) +if (NOT armral_INCLUDE_DIR) + message(FATAL_ERROR "could not detect armral header at ${armral_LOCATION}/include") +endif() + +find_library(armral_LIBRARY + NAMES armral + HINTS ${armral_LOCATION} + PATH_SUFFIXES lib build + NO_DEFAULT_PATH +) +if (NOT armral_LIBRARY) + message(FATAL_ERROR "could not detect armral build artifacts at neither ${armral_LOCATION}/lib nor ${armral_LOCATION}/build") +endif() + +# No way to retrieve the version from header or library +set(armral_VERSION 25.01) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(armral + FOUND_VAR armral_FOUND + REQUIRED_VARS + armral_LIBRARY + armral_INCLUDE_DIR + VERSION_VAR armral_VERSION +) + +if(armral_FOUND) + set(armral_LIBRARIES ${armral_LIBRARY}) + set(armral_INCLUDE_DIRS ${armral_INCLUDE_DIR}) +endif() + +if(armral_FOUND AND NOT TARGET armral) + add_library(armral UNKNOWN IMPORTED) + set_target_properties(armral PROPERTIES + IMPORTED_LOCATION "${armral_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${armral_INCLUDE_DIRS}" + ) +endif() + +mark_as_advanced( + armral_INCLUDE_DIR + armral_LIBRARY +) diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index 4a9064e661..cec59d38ad 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -32,6 +32,11 @@ add_compile_options(-Wno-packed-not-aligned) set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native") target_link_libraries(oran_fhlib_5g PRIVATE xran::xran ${dpdk_LINK_LIBRARIES} ${T_LIB} pthread dl rt m numa) target_include_directories(oran_fhlib_5g PRIVATE ${dpdk_INCLUDE_DIRS}) +if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + find_package(armral REQUIRED) + target_sources(oran_fhlib_5g PRIVATE armral_bfp_compression.c) + target_link_libraries(oran_fhlib_5g PRIVATE armral) +endif() add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON) diff --git a/radio/fhi_72/armral_bfp_compression.c b/radio/fhi_72/armral_bfp_compression.c new file mode 100644 index 0000000000..a02d4a4106 --- /dev/null +++ b/radio/fhi_72/armral_bfp_compression.c @@ -0,0 +1,116 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file radio/fhi_72/armral_bfp_compression.c + * \brief BFP compression for the O-RAN 7.2 FrontHaul Interface for Arm systems using the Arm RAN Acceleration Library + * \author Romain Beurdouche + * \date 2025 + * \company EURECOM + * \email romain.beurdouche@eurecom.fr + * \note ArmRAL available at https://git.gitlab.arm.com/networking/ral.git + * \warning + */ + +#include "armral.h" +#include + +#include "armral_bfp_compression.h" +#include "common/utils/LOG/log.h" + +/** + * The function operates on a fixed block size of one Physical Resource Block + * (PRB). Each block consists of 12 16-bit complex resource elements. Each block + * taken as input is compressed into 24 samples with a common unsigned scaling factor. + * + * @param[in] iq_width Width in bits of compressed samples. + * @param[in] n_prb The number of input resource blocks. + * @param[in] src Points to the input complex samples sequence. + * @param[out] dst Points to the output compressed data. + */ +void armral_bfp_compression(uint32_t iq_width, uint32_t n_prb, int16_t *src, int8_t *dst) +{ + armral_status ret = ARMRAL_ARGUMENT_ERROR; + switch (iq_width) { + case 8: + ret = armral_block_float_compr_8bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_8bit *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_compr_8bit returned an error: %d\n", (int)ret); + } + break; + + case 9: + ret = armral_block_float_compr_9bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_9bit *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_compr_9bit returned an error: %d\n", (int)ret); + } + break; + + case 14: + ret = armral_block_float_compr_14bit(n_prb, (armral_cmplx_int16_t *)src, (armral_compressed_data_14bit *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_compr_14bit returned an error: %d\n", (int)ret); + } + break; + + default: + LOG_E(HW, "Unsupported IQ width in BFP compression: %d\n", iq_width); + } +} + +/** + * The function operates on a fixed block size of one Physical Resource Block + * (PRB). Each block consists of 12 compressed complex resource elements. + * Each block taken as input is expanded into 12 16-bit complex samples. + * + * @param[in] iq_width Width in bits of compressed samples. + * @param[in] n_prb The number of input resource blocks. + * @param[in] src Points to the input compressed data. + * @param[out] dst Points to the output complex samples sequence. + */ +void armral_bfp_decompression(uint32_t iq_width, uint32_t n_prb, int8_t *src, int16_t *dst) +{ + armral_status ret = ARMRAL_ARGUMENT_ERROR; + switch (iq_width) { + case 8: + ret = armral_block_float_decompr_8bit(n_prb, (armral_compressed_data_8bit *)src, (armral_cmplx_int16_t *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_decompr_8bit returned an error: %d\n", (int)ret); + } + break; + + case 9: + ret = armral_block_float_decompr_9bit(n_prb, (armral_compressed_data_9bit *)src, (armral_cmplx_int16_t *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_decompr_9bit returned an error: %d\n", (int)ret); + } + break; + + case 14: + ret = armral_block_float_decompr_14bit(n_prb, (armral_compressed_data_14bit *)src, (armral_cmplx_int16_t *)dst, NULL); + if (unlikely(ret != ARMRAL_SUCCESS)) { + LOG_E(HW, "armral_block_scaling_decompr_14bit returned an error: %d\n", (int)ret); + } + break; + + default: + LOG_E(HW, "Unsupported IQ width in BFP decompression: %d\n", iq_width); + } +} diff --git a/radio/fhi_72/armral_bfp_compression.h b/radio/fhi_72/armral_bfp_compression.h new file mode 100644 index 0000000000..22cee0aa8b --- /dev/null +++ b/radio/fhi_72/armral_bfp_compression.h @@ -0,0 +1,59 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file radio/fhi_72/armral_bfp_compression.h + * \brief BFP compression for the O-RAN 7.2 FrontHaul Interface for Arm systems using the Arm RAN Acceleration Library + * \author Romain Beurdouche + * \date 2025 + * \company EURECOM + * \email romain.beurdouche@eurecom.fr + * \note ArmRAL available at https://git.gitlab.arm.com/networking/ral.git + * \warning + */ + +#ifndef __ARMRAL_BFP_COMPRESSION_H__ +#define __ARMRAL_BFP_COMPRESSION_H__ + +/** + * The function operates on a fixed block size of one Physical Resource Block + * (PRB). Each block consists of 12 16-bit complex resource elements. Each block + * taken as input is compressed into 24 samples with a common unsigned scaling factor. + * + * @param[in] iq_width Width in bits of compressed samples. + * @param[in] n_prb The number of input resource blocks. + * @param[in] src Points to the input complex samples sequence. + * @param[out] dst Points to the output compressed data. + */ +void armral_bfp_compression(uint32_t iq_width, uint32_t n_prb, int16_t *src, int8_t *dst); + +/** + * The function operates on a fixed block size of one Physical Resource Block + * (PRB). Each block consists of 12 compressed complex resource elements. + * Each block taken as input is expanded into 12 16-bit complex samples. + * + * @param[in] iq_width Width in bits of compressed samples. + * @param[in] n_prb The number of input resource blocks. + * @param[in] src Points to the input compressed data. + * @param[out] dst Points to the output complex samples sequence. + */ +void armral_bfp_decompression(uint32_t iq_width, uint32_t n_prb, int8_t *src, int16_t *dst); + +#endif diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index afa6384741..7ac4998e40 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -24,6 +24,7 @@ #include #include "xran_fh_o_du.h" #include "xran_compression.h" +#include "armral_bfp_compression.h" #if defined(__arm__) || defined(__aarch64__) #else @@ -215,12 +216,14 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) } } } else if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_BLKFLOAT) { - struct xranlib_decompress_request bfp_decom_req = {}; - struct xranlib_decompress_response bfp_decom_rsp = {}; int16_t local_dst[12 * 2 * N_SC_PER_PRB] __attribute__((aligned(64))); +#if defined(__i386__) || defined(__x86_64__) + struct xranlib_decompress_request bfp_decom_req = {}; + struct xranlib_decompress_response bfp_decom_rsp = {}; int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * 12; // 12 = closest number of PRBs to 139 REs + bfp_decom_req.data_in = (int8_t *)src; bfp_decom_req.numRBs = 12; // closest number of PRBs to 139 REs bfp_decom_req.len = payload_len; @@ -230,6 +233,11 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) bfp_decom_rsp.data_out = (int16_t *)local_dst; bfp_decom_rsp.len = 0; xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp); +#elif defined(__arm__) || defined(__aarch64__) + armral_bfp_decompression(ru_conf->iqWidth_PRACH, 12, (int8_t *)src, (int16_t *)local_dst); +#else + AssertFatal(1 == 0, "BFP decompression not supported on this architecture"); +#endif // note: this is hardwired for 139 point PRACH sequence, kbar=2 if (sym_idx == 0) // for (idx = 0; idx < (139 * 2); idx++) @@ -380,8 +388,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) uint32_t idxElm = 0; uint8_t *src = (uint8_t *)ptr; - int16_t payload_len = 0; - LOG_D(HW, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { @@ -412,10 +418,12 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) memcpy((void *)dst2, (void *)local_dst, neg_len * 4); memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4); } else if (pRbElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { +#if defined(__i386__) || defined(__x86_64__) struct xranlib_decompress_request bfp_decom_req = {}; struct xranlib_decompress_response bfp_decom_rsp = {}; - payload_len = (3 * pRbElm->iqWidth + 1) * pRbElm->nRBSize; + int16_t payload_len = (3 * pRbElm->iqWidth + 1) * pRbElm->nRBSize; + bfp_decom_req.data_in = (int8_t *)src; bfp_decom_req.numRBs = pRbElm->nRBSize; bfp_decom_req.len = payload_len; @@ -426,6 +434,11 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) bfp_decom_rsp.len = 0; xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp); +#elif defined(__arm__) || defined(__aarch64__) + armral_bfp_decompression(pRbElm->iqWidth, pRbElm->nRBSize, (int8_t *)src, (int16_t *)local_dst); +#else + AssertFatal(1 == 0, "BFP compression not supported on this architecture"); +#endif memcpy((void *)dst2, (void *)local_dst, neg_len * 4); memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4); outcnt++; @@ -552,9 +565,12 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) for (idx = 0; idx < (pos_len + neg_len) * 2; idx++) ((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]); } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { + payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->nRBSize; + +#if defined(__i386__) || defined(__x86_64__) struct xranlib_compress_request bfp_com_req = {}; struct xranlib_compress_response bfp_com_rsp = {}; - payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->nRBSize; + bfp_com_req.data_in = (int16_t *)local_src; bfp_com_req.numRBs = p_prbMapElm->nRBSize; bfp_com_req.len = payload_len; @@ -565,6 +581,11 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) bfp_com_rsp.len = 0; xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); +#elif defined(__arm__) || defined(__aarch64__) + armral_bfp_compression(p_prbMapElm->iqWidth, p_prbMapElm->nRBSize, (int16_t *)local_src, (int8_t *)dst); +#else + AssertFatal(1 == 0, "BFP compression not supported on this architecture"); +#endif } else { printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod); From e12bcc964dca21f634d5b785498f1255a192f3de Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 27 Mar 2025 13:17:18 +0000 Subject: [PATCH 6/9] feat(oran_fhlib_5g): Make F release patch dual Update the xran F release patch to work for Arm targets in addition to x86 targets. --- .../F/oaioran_F.patch | 1042 ++++++++++++++++- radio/fhi_72/CMakeLists.txt | 4 +- 2 files changed, 995 insertions(+), 51 deletions(-) diff --git a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch index 8ab8da6aad..5f55996d76 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch @@ -7,15 +7,15 @@ index ac5f471..bbd39fe 100644 #include -#define VERSIONX "oran_f_release_v1.0" -+#define VERSIONX "oran_f_release_v1.1" ++#define VERSIONX "oran_f_release_v1.2" #define APP_O_DU 0 #define APP_O_RU 1 diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile -index eccc4ae..8ddb22e 100644 +index eccc4ae..b1b8f4b 100644 --- a/fhi_lib/lib/Makefile +++ b/fhi_lib/lib/Makefile -@@ -23,12 +23,18 @@ MYCUSTOMSPACE1='------------------------------------------------------------' +@@ -23,24 +23,46 @@ MYCUSTOMSPACE1='------------------------------------------------------------' ############################################################## # Tools configuration ############################################################## @@ -25,31 +25,80 @@ index eccc4ae..8ddb22e 100644 -AS := as -AR := ar -LD := icc -+ifeq ($(WIRELESS_SDK_TOOLCHAIN),gcc) -+ CC := gcc +-else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx) +- CC := icx +- CPP := icpx +- AS := as +- AR := llvm-ar +- LD := icx ++ ++# Default target architecture and compiler ++TARGET ?= x86 ++ ++# Architecture and compiler-specific tools and flags ++ifeq ($(TARGET), x86) ++ ifeq ($(WIRELESS_SDK_TOOLCHAIN),gcc) ++ CC := gcc ++ CPP := g++ ++ AS := as ++ AR := ar ++ LD := gcc ++ else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc) ++ CC := icc ++ CPP := icpc ++ AS := as ++ AR := ar ++ LD := icc ++ else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx) ++ CC := icx ++ CPP := icpx ++ AS := as ++ AR := llvm-ar ++ LD := icx ++ else ++ $(error "Please define WIRELESS_SDK_TOOLCHAIN environment variable") ++ endif ++ ++ OBJDUMP := objdump ++ ++else ifeq ($(TARGET), armv8) # aarch64 ++ CC := gcc + CPP := g++ -+ AS := as -+ AR := ar + LD := gcc -+else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc) -+ CC := icc -+ CPP := icpc -+ AS := as -+ AR := ar -+ LD := icc - else ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx) - CC := icx - CPP := icpx -@@ -72,7 +78,7 @@ ifeq ($(RTE_SDK),) ++ CFLAGS += -march=armv8-a ++ LDFLAGS += + else +- $(error "Please define WIRELESS_SDK_TOOLCHAIN environment variable") ++ $(error Unsupported target architecture: $(TARGET)) + endif + +-OBJDUMP := objdump +- + ifeq ($(SHELL),cmd.exe) + MD := mkdir.exe -p + CP := cp.exe -f +@@ -72,7 +94,11 @@ ifeq ($(RTE_SDK),) endif RTE_TARGET ?= x86_64-native-linux-icc -RTE_INC := $(shell PKG_CONFIG_PATH=/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) ++ifeq ($(TARGET), x86) +RTE_INC := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH):/usr/lib64/pkgconfig:$(RTE_SDK)/build/meson-uninstalled pkgconf --cflags-only-I libdpdk) ++else ifeq ($(TARGET), armv8) ++RTE_INC := $(pkgconf --cflags-only-I libdpdk) ++endif API_DIR := $(PROJECT_DIR)/api SRC_DIR := $(PROJECT_DIR)/src -@@ -110,8 +116,7 @@ CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ +@@ -103,6 +129,7 @@ CC_SRC = $(ETH_DIR)/ethdi.c \ + $(SRC_DIR)/xran_main.c \ + $(SRC_DIR)/xran_delay_measurement.c + ++ifeq ($(TARGET), x86) + CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ + $(SRC_DIR)/xran_bfp_ref.cpp \ + $(SRC_DIR)/xran_bfp_cplane8.cpp \ +@@ -110,8 +137,7 @@ CPP_SRC = $(SRC_DIR)/xran_compression.cpp \ $(SRC_DIR)/xran_bfp_cplane32.cpp \ $(SRC_DIR)/xran_bfp_cplane64.cpp \ $(SRC_DIR)/xran_bfp_uplane_9b16rb.cpp \ @@ -59,35 +108,58 @@ index eccc4ae..8ddb22e 100644 CPP_SRC_SNC = $(SRC_DIR)/xran_compression_snc.cpp \ $(SRC_DIR)/xran_bfp_cplane8_snc.cpp \ -@@ -127,7 +132,7 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ +@@ -119,6 +145,7 @@ CPP_SRC_SNC = $(SRC_DIR)/xran_compression_snc.cpp \ + $(SRC_DIR)/xran_bfp_cplane32_snc.cpp \ + $(SRC_DIR)/xran_bfp_cplane64_snc.cpp \ + $(SRC_DIR)/xran_bfp_uplane_snc.cpp ++endif + + CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ + -fdata-sections \ +@@ -127,7 +154,11 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \ -fPIC \ -Wall \ -Wimplicit-function-declaration \ - -g -O3 -mcmodel=large -+ -g -O -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512#--wd1786 -mcmodel=large ++ -g -O ++ ++ifeq ($(TARGET), x86) ++CC_FLAGS += -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512#--wd1786 -mcmodel=large ++endif ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc) CC_FLAGS += -wd1786 -restrict -@@ -138,8 +143,9 @@ CC_FLAGS += -march=icelake-server -mintrinsic-promote -Wno-unused-function -Wno- +@@ -137,9 +168,15 @@ ifeq ($(WIRELESS_SDK_TOOLCHAIN),icx) + CC_FLAGS += -march=icelake-server -mintrinsic-promote -Wno-unused-function -Wno-intrinsic-promote -Wno-error endif - CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \ -- -falign-functions=16 \ -- -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -fPIC ++ifeq ($(TARGET), x86) ++CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \ + -fPIC \ + -falign-functions=16 \ + -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512 ++else ifeq ($(TARGET), armv8) + CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe \ +- -falign-functions=16 \ +- -Werror -Wno-unused-variable -std=c++14 -mcmodel=large -fPIC ++ -Werror -Wno-unused-variable -std=c++14 ++endif ifeq ($(WIRELESS_SDK_TOOLCHAIN),icc) CPP_FLAGS += -fp-model fast=2 -no-prec-div -no-prec-sqrt -fast-transcendentals -restrict -@@ -186,8 +192,8 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) +@@ -186,8 +223,13 @@ CPP_SNC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS_SNC)) AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS)) #-qopt-report=5 -qopt-matmul -qopt-report-phase=all -CPP_COMP := -O3 -DNDEBUG -xcore-avx512 -fPIE -fasm-blocks -CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE -fasm-blocks ++ifeq ($(TARGET), x86) +CPP_COMP := -O3 -DNDEBUG -fPIE +CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE ++else ifeq ($(TARGET), armv8) ++CPP_COMP := -O3 -DNDEBUG -fPIE -Wrestrict ++CPP_COMP_SNC := -O3 -DNDEBUG -march=icelake-server -fPIE -Wrestrict ++endif CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF) CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF) CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF) @@ -127,6 +199,34 @@ index bacf597..90a42a2 100644 /** * @ingroup xran * +diff --git a/fhi_lib/lib/api/xran_pkt_cp.h b/fhi_lib/lib/api/xran_pkt_cp.h +index 33e96b3..a2f8ad0 100644 +--- a/fhi_lib/lib/api/xran_pkt_cp.h ++++ b/fhi_lib/lib/api/xran_pkt_cp.h +@@ -33,6 +33,14 @@ + extern "C" { + #endif + ++#include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++typedef int32x4_t simd_data_t; ++#else ++#include ++typedef __m128i simd_data_t; ++#endif + + /********************************************************************** + * Common structures for C/U-plane +@@ -256,7 +264,7 @@ union xran_cp_radioapp_section_ext3_first { + }all_bits; + + struct{ +- __m128i data_field1; ++ simd_data_t data_field1; + }data_field; + } __attribute__((__packed__)); + diff --git a/fhi_lib/lib/api/xran_up_api.h b/fhi_lib/lib/api/xran_up_api.h index 46e0e1d..409ef4b 100644 --- a/fhi_lib/lib/api/xran_up_api.h @@ -150,10 +250,21 @@ index 46e0e1d..409ef4b 100644 int xran_prepare_iq_symbol_portion( struct rte_mbuf *mbuf, diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c -index f5b2fd6..e949fe7 100644 +index f5b2fd6..144a65e 100644 --- a/fhi_lib/lib/ethernet/ethdi.c +++ b/fhi_lib/lib/ethernet/ethdi.c -@@ -325,8 +325,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -37,7 +37,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +@@ -325,8 +328,8 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, char bbdev_wdev[32] = ""; char bbdev_vdev[32] = ""; char iova_mode[32] = "--iova-mode=pa"; @@ -164,7 +275,7 @@ index f5b2fd6..e949fe7 100644 char ring_name[32] = ""; int32_t xran_port = -1; queueid_t qi = 0; -@@ -336,7 +336,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -336,7 +339,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, cpu = sched_getcpu(); node = numa_node_of_cpu(cpu); @@ -173,7 +284,7 @@ index f5b2fd6..e949fe7 100644 "--file-prefix", name, "-a0000:00:00.0", bbdev_wdev, bbdev_vdev}; if (io_cfg == NULL) -@@ -481,11 +481,13 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -481,11 +484,13 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, ctx->tx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING_TRX, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); PANIC_ON(ctx->tx_ring[i] == NULL, "failed to allocate rx ring"); @@ -187,7 +298,7 @@ index f5b2fd6..e949fe7 100644 } } } else { -@@ -555,7 +557,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, +@@ -555,7 +560,7 @@ xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, ctx->up_dl_pkt_gen_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), /*RING_F_SC_DEQ*/0); PANIC_ON(ctx->up_dl_pkt_gen_ring[i] == NULL, "failed to allocate dl gen ring"); @@ -196,6 +307,21 @@ index f5b2fd6..e949fe7 100644 } return 1; +diff --git a/fhi_lib/lib/ethernet/ethernet.c b/fhi_lib/lib/ethernet/ethernet.c +index edda598..791256c 100644 +--- a/fhi_lib/lib/ethernet/ethernet.c ++++ b/fhi_lib/lib/ethernet/ethernet.c +@@ -37,7 +37,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include diff --git a/fhi_lib/lib/src/xran_bfp_ref.cpp b/fhi_lib/lib/src/xran_bfp_ref.cpp index e6d3067..8e0abee 100644 --- a/fhi_lib/lib/src/xran_bfp_ref.cpp @@ -246,11 +372,37 @@ index 59b6850..322d238 100644 -} \ No newline at end of file +} +diff --git a/fhi_lib/lib/src/xran_cb_proc.c b/fhi_lib/lib/src/xran_cb_proc.c +index 08660f3..2bb5187 100644 +--- a/fhi_lib/lib/src/xran_cb_proc.c ++++ b/fhi_lib/lib/src/xran_cb_proc.c +@@ -25,7 +25,10 @@ + + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c -index dc40ad9..4ac1fbf 100644 +index dc40ad9..5968d01 100644 --- a/fhi_lib/lib/src/xran_common.c +++ b/fhi_lib/lib/src/xran_common.c -@@ -714,11 +714,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -31,7 +31,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +@@ -714,11 +717,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) uint8_t compMeth = 0; uint8_t iqWidth = 0; @@ -265,7 +417,7 @@ index dc40ad9..4ac1fbf 100644 if(first_call == 0) return ret; -@@ -733,9 +736,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -733,9 +739,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) return MBUF_FREE; num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf, @@ -277,7 +429,7 @@ index dc40ad9..4ac1fbf 100644 if (num_bytes <= 0) { print_err("num_bytes is wrong [%d]\n", num_bytes); -@@ -781,10 +784,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -781,10 +787,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) else { @@ -291,7 +443,7 @@ index dc40ad9..4ac1fbf 100644 #ifndef FCN_ADAPT if(valid_res != 0) { -@@ -807,8 +809,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -807,8 +812,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) PrachCfg = &(p_dev_ctx->PrachCPConfig); } @@ -301,7 +453,7 @@ index dc40ad9..4ac1fbf 100644 /* PRACH packet has ruportid = num_eAxc + ant_id */ Ant_ID -= PrachCfg->eAxC_offset; symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes; -@@ -1412,7 +1413,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc +@@ -1412,7 +1416,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx) { timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu @@ -310,7 +462,7 @@ index dc40ad9..4ac1fbf 100644 timeOffset += 16; } else -@@ -1547,8 +1548,7 @@ int32_t ring_processing_func(void* args) +@@ -1547,8 +1551,7 @@ int32_t ring_processing_func(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){ for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) { @@ -360,11 +512,159 @@ index 112caae..7c74342 100644 return xranlib_decompress_avxsnc_bfw(request,response); } else { return xranlib_decompress_avx512_bfw(request,response); +diff --git a/fhi_lib/lib/src/xran_cp_api.c b/fhi_lib/lib/src/xran_cp_api.c +index 4498b33..8a2984f 100644 +--- a/fhi_lib/lib/src/xran_cp_api.c ++++ b/fhi_lib/lib/src/xran_cp_api.c +@@ -25,7 +25,11 @@ + * @author Intel Corporation + * + **/ ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + #include + #include + +@@ -853,7 +857,11 @@ xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *p + | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId) + | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers); + data_fourth_byte = params->beamIdAP1; ++#if defined(__arm__) || defined(__aarch64__) ++ ext3_f->data_field.data_field1 = (int32x4_t){data_first_byte, data_second_byte, data_third_byte, data_fourth_byte}; ++#else + ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte); ++#endif + + /* convert byte order */ + tmp = (uint64_t *)ext3_f; +diff --git a/fhi_lib/lib/src/xran_cp_proc.c b/fhi_lib/lib/src/xran_cp_proc.c +index 789c6fd..a768efb 100644 +--- a/fhi_lib/lib/src/xran_cp_proc.c ++++ b/fhi_lib/lib/src/xran_cp_proc.c +@@ -35,7 +35,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + + #include + #include +diff --git a/fhi_lib/lib/src/xran_delay_measurement.c b/fhi_lib/lib/src/xran_delay_measurement.c +index 4c943c8..d9e7983 100644 +--- a/fhi_lib/lib/src/xran_delay_measurement.c ++++ b/fhi_lib/lib/src/xran_delay_measurement.c +@@ -23,7 +23,10 @@ + * @author Intel Corporation + **/ + #define _GNU_SOURCE ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +diff --git a/fhi_lib/lib/src/xran_dev.c b/fhi_lib/lib/src/xran_dev.c +index 4acade1..c939edc 100644 +--- a/fhi_lib/lib/src/xran_dev.c ++++ b/fhi_lib/lib/src/xran_dev.c +@@ -35,7 +35,10 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + #include +@@ -55,6 +58,27 @@ + + static struct xran_device_ctx *g_xran_dev_ctx[XRAN_PORTS_NUM] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + ++struct xran_device_ctx *allocate_device_ctx(size_t xran_ports_num, size_t alignment) { ++ void *ptr = NULL; ++ ++#if defined(__arm__) || defined(__aarch64__) ++ // ARM-specific memory allocation ++ if (posix_memalign(&ptr, alignment, sizeof(struct xran_device_ctx) * xran_ports_num) != 0) { ++ print_err("posix_memalign: pCtx allocation error\n"); ++ return NULL; ++ } ++#else ++ // Intel-specific memory allocation ++ ptr = _mm_malloc(sizeof(struct xran_device_ctx) * xran_ports_num, alignment); ++ if (ptr == NULL) { ++ print_err("_mm_malloc: pCtx allocation error\n"); ++ return NULL; ++ } ++#endif ++ ++ return (struct xran_device_ctx *)ptr; ++} ++ + int32_t + xran_dev_create_ctx(uint32_t xran_ports_num) + { +@@ -64,7 +88,7 @@ xran_dev_create_ctx(uint32_t xran_ports_num) + if (xran_ports_num > XRAN_PORTS_NUM) + return -1; + +- pCtx = (struct xran_device_ctx *) _mm_malloc(sizeof(struct xran_device_ctx)*xran_ports_num, 64); ++ pCtx = allocate_device_ctx(xran_ports_num, 64); + if(pCtx){ + for(i = 0; i < xran_ports_num; i++){ + g_xran_dev_ctx[i] = pCtx; diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c -index 7c472d7..7bab6a8 100644 +index 7c472d7..216c7f5 100644 --- a/fhi_lib/lib/src/xran_main.c +++ b/fhi_lib/lib/src/xran_main.c -@@ -306,7 +306,7 @@ xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_de +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + #include + #include + #include +@@ -103,6 +107,25 @@ void tti_to_phy_cb(struct rte_timer *tim, void *arg); + + int32_t xran_pkt_gen_process_ring(struct rte_ring *r); + ++void *mm_allocate_handle(size_t size, size_t alignment) { ++ void *ptr = NULL; ++#if defined(__arm__) || defined(__aarch64__) ++ // ARM-specific memory allocation ++ if (posix_memalign(&ptr, alignment, size) != 0) { ++ fprintf(stderr, "posix_memalign: allocation error\n"); ++ return NULL; ++ } ++#else ++ // Intel-specific memory allocation ++ ptr = _mm_malloc(size, alignment); ++ if (ptr == NULL) { ++ fprintf(stderr, "_mm_malloc: allocation error\n"); ++ return NULL; ++ } ++#endif ++ return ptr; ++} ++ + void + xran_updateSfnSecStart(void) + { +@@ -306,7 +329,7 @@ xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_de printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]); } @@ -373,7 +673,7 @@ index 7c472d7..7bab6a8 100644 print_dbg("PRACH eAxC_offset %d\n", pPrachCPConfig->eAxC_offset); /* Save some configs for app */ -@@ -1570,6 +1570,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1570,6 +1593,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru { case ECPRI_IQ_DATA: pkt_data[num_data++] = pkt; @@ -381,7 +681,7 @@ index 7c472d7..7bab6a8 100644 break; // For RU emulation case ECPRI_RT_CONTROL_DATA: -@@ -1587,7 +1588,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1587,7 +1611,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru break; default: if (p_dev_ctx->fh_init.io_cfg.id == O_DU) { @@ -390,7 +690,16 @@ index 7c472d7..7bab6a8 100644 } break; } -@@ -2347,8 +2348,7 @@ ring_processing_func_per_port(void* args) +@@ -1876,7 +1900,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI + for (i = 0; i < nNumInstances; i++) { + + /* Allocate Memory for CC handles */ +- pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64); ++ pCcHandle = (XranSectorHandleInfo *)mm_allocate_handle( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64); + + if(pCcHandle == NULL) + return XRAN_STATUS_RESOURCE; +@@ -2347,8 +2371,7 @@ ring_processing_func_per_port(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) { if (ctx->vf2xran_port[i] == port_id) { for(qi = 0; qi < ctx->rxq_per_port[port_id]; qi++){ @@ -400,7 +709,7 @@ index 7c472d7..7bab6a8 100644 } } } -@@ -2414,9 +2414,6 @@ xran_spawn_workers(void) +@@ -2414,9 +2437,6 @@ xran_spawn_workers(void) nWorkerCore = nWorkerCore << 1; } @@ -410,7 +719,520 @@ index 7c472d7..7bab6a8 100644 printf("O-XU %d\n", eth_ctx->io_cfg.id); printf("HW %d\n", icx_cpu); printf("Num cores %d\n", total_num_cores); -@@ -4034,6 +4031,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, +@@ -2453,7 +2473,7 @@ xran_spawn_workers(void) + eth_ctx->time_wrk_cfg.arg = NULL; + eth_ctx->time_wrk_cfg.state = 1; + +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2475,7 +2495,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2502,7 +2522,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2536,7 +2556,7 @@ xran_spawn_workers(void) + else + p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; + +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2559,7 +2579,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2586,7 +2606,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2613,7 +2633,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2628,7 +2648,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2643,7 +2663,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2682,7 +2702,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2697,7 +2717,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2712,7 +2732,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2727,7 +2747,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2766,7 +2786,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2781,7 +2801,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 Eth Tx **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); +@@ -2797,7 +2817,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2812,7 +2832,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2827,7 +2847,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 4 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2861,7 +2881,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 Eth RX */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2876,7 +2896,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2891,7 +2911,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2906,7 +2926,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2921,7 +2941,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** FH TX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -2969,7 +2989,7 @@ xran_spawn_workers(void) + + /* p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; */ + +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3004,7 +3024,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3031,7 +3051,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3062,7 +3082,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3089,7 +3109,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3115,7 +3135,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3130,7 +3150,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3145,7 +3165,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3184,7 +3204,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3199,7 +3219,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3214,7 +3234,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3229,7 +3249,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3266,7 +3286,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3281,7 +3301,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3296,7 +3316,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3311,7 +3331,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3326,7 +3346,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 4 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3348,7 +3368,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 Eth RX */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3363,7 +3383,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3378,7 +3398,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3393,7 +3413,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3408,7 +3428,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** FH TX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3435,7 +3455,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 Eth RX */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3450,7 +3470,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 1 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3465,7 +3485,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3480,7 +3500,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 3 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3495,7 +3515,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 4 FH RX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3510,7 +3530,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** FH TX and BBDEV */ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3537,7 +3557,7 @@ xran_spawn_workers(void) + + /* workers */ + /** 0 **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3562,7 +3582,7 @@ xran_spawn_workers(void) + } + + /** 1 - CP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3577,7 +3597,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 2 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3602,7 +3622,7 @@ xran_spawn_workers(void) + } + + /** 3 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3627,7 +3647,7 @@ xran_spawn_workers(void) + } + + /** 4 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -3642,7 +3662,7 @@ xran_spawn_workers(void) + eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; + + /** 5 UP GEN **/ +- pThCtx = (struct xran_worker_th_ctx*) _mm_malloc(sizeof(struct xran_worker_th_ctx), 64); ++ pThCtx = (struct xran_worker_th_ctx*)mm_allocate_handle(sizeof(struct xran_worker_th_ctx), 64); + if(pThCtx == NULL){ + print_err("pThCtx allocation error\n"); + return XRAN_STATUS_FAIL; +@@ -4034,6 +4054,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, return tti; } @@ -435,6 +1257,22 @@ index 7c472d7..7bab6a8 100644 int32_t xran_set_debug_stop(int32_t value, int32_t count) { +diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c +index e1dcb6c..b3c3fae 100644 +--- a/fhi_lib/lib/src/xran_mem_mgr.c ++++ b/fhi_lib/lib/src/xran_mem_mgr.c +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include diff --git a/fhi_lib/lib/src/xran_mod_compression.cpp b/fhi_lib/lib/src/xran_mod_compression.cpp index 7d4a5d0..b9b44ac 100644 --- a/fhi_lib/lib/src/xran_mod_compression.cpp @@ -451,11 +1289,117 @@ index 7d4a5d0..b9b44ac 100644 return (xranlib_5gnr_mod_compression_avx512(request, response)); #endif } +diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c +index e7056f4..0d3d8ac 100644 +--- a/fhi_lib/lib/src/xran_rx_proc.c ++++ b/fhi_lib/lib/src/xran_rx_proc.c +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include +diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c +index 14a6a41..55182d8 100644 +--- a/fhi_lib/lib/src/xran_timer.c ++++ b/fhi_lib/lib/src/xran_timer.c +@@ -29,7 +29,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + #include "xran_timer.h" + #include "xran_printf.h" + #include "xran_mlog_lnx.h" +@@ -141,12 +145,30 @@ void timing_adjust_gps_second(struct timespec* p_time) + + return; + } ++#if defined(__x86_64__) + uint64_t xran_tick(void) + { + uint32_t hi, lo; + __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 ); + } ++#elif defined(__aarch64__) ++#include ++uint64_t xran_tick(void) { ++ struct timeval tv; ++ gettimeofday(&tv, NULL); ++ return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec; ++} ++#elif defined(__arm__) ++#include ++uint64_t xran_tick(void) { ++ struct timespec ts; ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ return (uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec; ++} ++#else ++#error "Unsupported architecture" ++#endif + + unsigned long get_ticks_diff(unsigned long curr_tick, unsigned long last_tick) + { +diff --git a/fhi_lib/lib/src/xran_transport.c b/fhi_lib/lib/src/xran_transport.c +index 72249bc..6b30084 100644 +--- a/fhi_lib/lib/src/xran_transport.c ++++ b/fhi_lib/lib/src/xran_transport.c +@@ -27,7 +27,10 @@ + + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif + #include + #include + +diff --git a/fhi_lib/lib/src/xran_tx_proc.c b/fhi_lib/lib/src/xran_tx_proc.c +index 45a17a8..28c5568 100644 +--- a/fhi_lib/lib/src/xran_tx_proc.c ++++ b/fhi_lib/lib/src/xran_tx_proc.c +@@ -35,7 +35,11 @@ + #include + #include + #include ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#else + #include ++#endif + + #include + #include diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c -index fe22a1f..f6c4830 100644 +index fe22a1f..3fd369b 100644 --- a/fhi_lib/lib/src/xran_up_api.c +++ b/fhi_lib/lib/src/xran_up_api.c -@@ -336,6 +336,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -25,7 +25,11 @@ + * + **/ + #include ++#if defined(__arm__) || defined(__aarch64__) ++#else + #include ++#endif ++#include + #include + + #include "xran_fh_o_du.h" +@@ -336,6 +340,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, uint8_t *subframe_id, uint8_t *slot_id, uint8_t *symb_id, @@ -463,7 +1407,7 @@ index fe22a1f..f6c4830 100644 union ecpri_seq_id *seq_id, uint16_t *num_prbu, uint16_t *start_prbu, -@@ -345,7 +346,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -345,7 +350,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, int8_t expect_comp, enum xran_comp_hdr_type staticComp, uint8_t *compMeth, @@ -473,7 +1417,7 @@ index fe22a1f..f6c4830 100644 { #if XRAN_MLOG_VAR uint32_t mlogVar[10]; -@@ -381,6 +383,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -381,6 +387,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, return 0; /* packet too short */ radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value); @@ -481,7 +1425,7 @@ index fe22a1f..f6c4830 100644 if (frame_id) *frame_id = radio_hdr->frame_id; -@@ -394,6 +397,9 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, +@@ -394,6 +401,9 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, if (symb_id) *symb_id = radio_hdr->sf_slot_sym.symb_id; diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index cec59d38ad..0b78bf055b 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -19,10 +19,10 @@ add_library(oran_fhlib_5g MODULE find_package(xran REQUIRED) if(xran_VERSION VERSION_EQUAL 5.1.5) target_compile_definitions(oran_fhlib_5g PRIVATE E_RELEASE) -elseif(xran_VERSION VERSION_EQUAL 6.1.1) +elseif(xran_VERSION VERSION_EQUAL 6.1.2) target_compile_definitions(oran_fhlib_5g PRIVATE F_RELEASE) else() - message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.5 (E release) or 6.1.1 (F release)") + message(FATAL_ERROR "Found xran version ${xran_VERSION} but needed 5.1.5 (E release) or 6.1.2 (F release)") endif() # Ignore xran-specific warning: we don't care/can't change the following warning, so suppress From 09aec7f1d8b9a73fa5ae355db9ec193f63ed052e Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 27 Mar 2025 10:56:19 +0000 Subject: [PATCH 7/9] feat(oran_fhlib_5g): Documentation for Arm targets --- doc/ORAN_FHI7.2_Tutorial.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index b3bd8ce146..07612062f5 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -403,7 +403,8 @@ git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/ Compile the fronthaul interface library by calling `make` and the option `XRAN_LIB_SO=1` to have it build a shared object. Note that we provide two environment variables `RTE_SDK` for the path to the source tree of DPDK, and -`XRAN_DIR` to set the path to the fronthaul library. +`XRAN_DIR` to set the path to the fronthaul library. +For building for a Arm target, set as well the environment variable `TARGET=armv8`. **Note**: you need at least gcc-11 and g++-11. @@ -420,6 +421,28 @@ WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib The shared library object `~/phy/fhi_lib/lib/build/libxran.so` must be present before proceeding. +## For Arm targets only: Install the Arm RAN Acceleration library + +Clone, configure and build ArmRAL: + +Note: Use option `-DCMAKE_INSTALL_PREFIX=` of cmake to set the installation directory of ArmRAL to ``. +If you omit this option, ArmRAL is installed into `/usr/local`. + +``` +git clone https://git.gitlab.arm.com/networking/ral.git ~/ral +cd ~/ral +git checkout armral-25.01 +mkdir build +cd build +cmake -GNinja -DBUILD_SHARED_LIBS=On ../ +ninja +``` + +Once ArmRAL is configured at your convenience and built, you can install it: +``` +ninja install +``` + ## Build OAI gNB You can now proceed building OAI. You build it the same way as for other From 96a47821dec265d82da2f098b35d02456dc45adc Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Fri, 28 Mar 2025 13:41:01 +0000 Subject: [PATCH 8/9] feat(CI): Add FHI 7.2 build on native Arm build pipeline --- ci-scripts/cls_containerize.py | 1 + ...Dockerfile.build.fhi72.native_arm.ubuntu22 | 101 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 docker/Dockerfile.build.fhi72.native_arm.ubuntu22 diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index dc461dfe7e..b697069da2 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -410,6 +410,7 @@ class Containerize(): result = re.search('native_arm', self.imageKind) if result is not None: imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', '')) + imageNames.append(('ran-build-fhi72', 'build.fhi72.native_arm', 'ran-build-fhi72', '')) imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', '')) imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', '')) imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', '')) diff --git a/docker/Dockerfile.build.fhi72.native_arm.ubuntu22 b/docker/Dockerfile.build.fhi72.native_arm.ubuntu22 new file mode 100644 index 0000000000..4ea1bcd7bb --- /dev/null +++ b/docker/Dockerfile.build.fhi72.native_arm.ubuntu22 @@ -0,0 +1,101 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface RAN Build for FHI 7.2 +# Valid for UBUNTU 22.04 +# +#--------------------------------------------------------------------- + +FROM ran-base:latest AS ran-base + +ARG E2AP_VERSION=E2AP_V3 +ARG KPM_VERSION=KPM_V3_00 +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + meson \ + wget \ + xz-utils \ + pkg-config \ + libnuma-dev && \ + rm -rf /var/lib/apt/lists/* + +RUN rm -Rf /oai-ran +WORKDIR /oai-ran +COPY . . + +## Download and build DPDK +RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \ + tar -xvf dpdk-20.11.9.tar.xz && \ + cd dpdk-stable-20.11.9 && \ + meson build && \ + ninja -C build && \ + ninja install -C build + +## Build Fronthaul library +RUN git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git /opt/phy && \ + cd /opt/phy && \ + git checkout oran_f_release_v1.0 &&\ + git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \ + cd /opt/phy/fhi_lib/lib && \ + TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1 + +## Build Arm RAN Acceleration Library +RUN git clone https://git.gitlab.arm.com/networking/ral.git /opt/ral && \ + cd /opt/ral && \ + git checkout armral-25.01 &&\ + mkdir build && \ + cd build && \ + cmake -GNinja -DBUILD_SHARED_LIBS=On /opt/ral/ && \ + ninja && \ + ninja install + +FROM ran-base AS ran-build-fhi72 +## Build and install OAI +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai \ + --gNB \ + --build-lib "telnetsrv enbscope uescope nrscope" \ + -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \ + --build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \ + $BUILD_OPTION && \ + # Mainly to see if the sanitize option was perfectly executed + ldd ran_build/build/nr-softmodem && \ + ldd ran_build/build/liboran_fhlib_5g.so && \ + ldd /opt/phy/fhi_lib/lib/build/libxran.so + +## Build FlexRIC for SM Models +RUN mkdir -p openair2/E2AP/flexric/build && \ + cd openair2/E2AP/flexric/build && \ + cmake -GNinja -DCMAKE_BUILD_TYPE=Release \ + -DXAPP_MULTILANGUAGE=OFF \ + -DKPM_VERSION=$KPM_VERSION \ + -DE2AP_VERSION=$E2AP_VERSION \ + -DCMAKE_C_COMPILER=gcc-12 \ + -DCMAKE_CXX_COMPILER=g++-12 .. && \ + ninja && \ + ninja install From fb3678bea45bc8096b56cbb939e2077d1b183c5d Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 3 Apr 2025 11:59:19 +0000 Subject: [PATCH 9/9] feat(oran_fhlib_5g): Arm support information in documentation Inform in O-RAN 7.2 documentation that DU execution on Arm is yet not fully supported and that 7.2 on Arm is only intended to enable experiments. --- doc/ORAN_FHI7.2_Tutorial.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index 07612062f5..df72be82c6 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -32,6 +32,8 @@ The hardware on which we have tried this tutorial: - The NIC card should support hardware PTP time stamping. - If you are using Intel servers then use only Ice Lake or newer generations. In case of AMD use only 4th generation, Genoa or newer. - If you try on any other server apart from the above listed, then choose a desktop/server with clock speed higher than 3.0 GHz and `avx512` capabilities. +- This tutorial gives few instructions for Arm targets, but DU execution on Arm systems is yet not functional. +This feature is intended to enable experiments and future improvements on Arm systems. NICs we have tested so far: @@ -405,6 +407,8 @@ Compile the fronthaul interface library by calling `make` and the option environment variables `RTE_SDK` for the path to the source tree of DPDK, and `XRAN_DIR` to set the path to the fronthaul library. For building for a Arm target, set as well the environment variable `TARGET=armv8`. +DU execution on Arm systems is yet not functional. +This feature is intended to enable experiments and future improvements on Arm systems. **Note**: you need at least gcc-11 and g++-11. @@ -423,6 +427,9 @@ before proceeding. ## For Arm targets only: Install the Arm RAN Acceleration library +DU execution on Arm systems is yet not functional. +This feature is intended to enable experiments and future improvements on Arm systems. + Clone, configure and build ArmRAL: Note: Use option `-DCMAKE_INSTALL_PREFIX=` of cmake to set the installation directory of ArmRAL to ``.