1# SPDX-License-Identifier: BSD-3-Clause 2# Copyright(c) 2017 Intel Corporation. 3# Copyright(c) 2017 Cavium, Inc 4# Copyright(c) 2021 PANTHEON.tech s.r.o. 5 6# common flags to all aarch64 builds, with lowest priority 7flags_common = [ 8 # Accelerate rte_memcpy. Be sure to run unit test (memcpy_perf_autotest) 9 # to determine the best threshold in code. Refer to notes in source file 10 # (lib/eal/arm/include/rte_memcpy_64.h) for more info. 11 ['RTE_ARCH_ARM64_MEMCPY', false], 12 # ['RTE_ARM64_MEMCPY_ALIGNED_THRESHOLD', 2048], 13 # ['RTE_ARM64_MEMCPY_UNALIGNED_THRESHOLD', 512], 14 # Leave below RTE_ARM64_MEMCPY_xxx options commented out, 15 # unless there are strong reasons. 16 # ['RTE_ARM64_MEMCPY_SKIP_GCC_VER_CHECK', false], 17 # ['RTE_ARM64_MEMCPY_ALIGN_MASK', 0xF], 18 # ['RTE_ARM64_MEMCPY_STRICT_ALIGN', false], 19 20 ['RTE_ARM_USE_WFE', false], 21 ['RTE_ARCH_ARM64', true], 22 ['RTE_CACHE_LINE_SIZE', 128] 23] 24 25## Part numbers are specific to Arm implementers 26# implementer specific armv8 flags have middle priority 27# (will overwrite common flags) 28# part number specific armv8 flags have higher priority 29# (will overwrite both common and implementer specific flags) 30implementer_generic = { 31 'description': 'Generic armv8', 32 'flags': [ 33 ['RTE_MACHINE', '"armv8a"'], 34 ['RTE_USE_C11_MEM_MODEL', true], 35 ['RTE_MAX_LCORE', 256], 36 ['RTE_MAX_NUMA_NODES', 4] 37 ], 38 'part_number_config': { 39 'generic': { 40 'march': 'armv8-a', 41 'march_features': ['crc'], 42 'compiler_options': ['-moutline-atomics'] 43 }, 44 'generic_aarch32': { 45 'march': 'armv8-a', 46 'compiler_options': ['-mfpu=neon'], 47 'flags': [ 48 ['RTE_ARCH_ARM_NEON_MEMCPY', false], 49 ['RTE_ARCH_STRICT_ALIGN', true], 50 ['RTE_ARCH_ARMv8_AARCH32', true], 51 ['RTE_ARCH', 'armv8_aarch32'], 52 ['RTE_CACHE_LINE_SIZE', 64] 53 ] 54 } 55 } 56} 57 58part_number_config_arm = { 59 '0xd03': {'compiler_options': ['-mcpu=cortex-a53']}, 60 '0xd04': {'compiler_options': ['-mcpu=cortex-a35']}, 61 '0xd07': {'compiler_options': ['-mcpu=cortex-a57']}, 62 '0xd08': {'compiler_options': ['-mcpu=cortex-a72']}, 63 '0xd09': {'compiler_options': ['-mcpu=cortex-a73']}, 64 '0xd0a': {'compiler_options': ['-mcpu=cortex-a75']}, 65 '0xd0b': {'compiler_options': ['-mcpu=cortex-a76']}, 66 '0xd0c': { 67 'march': 'armv8.2-a', 68 'march_features': ['crypto'], 69 'compiler_options': ['-mcpu=neoverse-n1'], 70 'flags': [ 71 ['RTE_MACHINE', '"neoverse-n1"'], 72 ['RTE_ARM_FEATURE_ATOMICS', true], 73 ['RTE_MAX_MEM_MB', 1048576], 74 ['RTE_MAX_LCORE', 160], 75 ['RTE_MAX_NUMA_NODES', 2] 76 ] 77 }, 78 '0xd49': { 79 'march': 'armv8.5-a', 80 'march_features': ['sve2'], 81 'flags': [ 82 ['RTE_MACHINE', '"neoverse-n2"'], 83 ['RTE_ARM_FEATURE_ATOMICS', true], 84 ['RTE_MAX_LCORE', 64], 85 ['RTE_MAX_NUMA_NODES', 1] 86 ] 87 } 88} 89implementer_arm = { 90 'description': 'Arm', 91 'flags': [ 92 ['RTE_MACHINE', '"armv8a"'], 93 ['RTE_USE_C11_MEM_MODEL', true], 94 ['RTE_CACHE_LINE_SIZE', 64], 95 ['RTE_MAX_LCORE', 64], 96 ['RTE_MAX_NUMA_NODES', 4] 97 ], 98 'part_number_config': part_number_config_arm 99} 100 101flags_part_number_thunderx = [ 102 ['RTE_MACHINE', '"thunderx"'], 103 ['RTE_USE_C11_MEM_MODEL', false] 104] 105implementer_cavium = { 106 'description': 'Cavium', 107 'flags': [ 108 ['RTE_MAX_VFIO_GROUPS', 128], 109 ['RTE_MAX_LCORE', 96], 110 ['RTE_MAX_NUMA_NODES', 2] 111 ], 112 'part_number_config': { 113 '0xa1': { 114 'compiler_options': ['-mcpu=thunderxt88'], 115 'flags': flags_part_number_thunderx 116 }, 117 '0xa2': { 118 'compiler_options': ['-mcpu=thunderxt81'], 119 'flags': flags_part_number_thunderx 120 }, 121 '0xa3': { 122 'compiler_options': ['-mcpu=thunderxt83'], 123 'flags': flags_part_number_thunderx 124 }, 125 '0xaf': { 126 'march': 'armv8.1-a', 127 'march_features': ['crc', 'crypto'], 128 'compiler_options': ['-mcpu=thunderx2t99'], 129 'flags': [ 130 ['RTE_MACHINE', '"thunderx2"'], 131 ['RTE_ARM_FEATURE_ATOMICS', true], 132 ['RTE_USE_C11_MEM_MODEL', true], 133 ['RTE_CACHE_LINE_SIZE', 64], 134 ['RTE_MAX_LCORE', 256] 135 ] 136 }, 137 '0xb2': { 138 'march': 'armv8.2-a', 139 'march_features': ['crc', 'crypto', 'lse'], 140 'compiler_options': ['-mcpu=octeontx2'], 141 'flags': [ 142 ['RTE_MACHINE', '"cn9k"'], 143 ['RTE_ARM_FEATURE_ATOMICS', true], 144 ['RTE_USE_C11_MEM_MODEL', true], 145 ['RTE_MAX_LCORE', 36], 146 ['RTE_MAX_NUMA_NODES', 1] 147 ] 148 } 149 } 150} 151 152implementer_ampere = { 153 'description': 'Ampere Computing', 154 'flags': [ 155 ['RTE_MACHINE', '"emag"'], 156 ['RTE_CACHE_LINE_SIZE', 64], 157 ['RTE_MAX_LCORE', 32], 158 ['RTE_MAX_NUMA_NODES', 1] 159 ], 160 'part_number_config': { 161 '0x0': { 162 'march': 'armv8-a', 163 'march_features': ['crc', 'crypto'], 164 'compiler_options': ['-mtune=emag'] 165 } 166 } 167} 168 169implementer_hisilicon = { 170 'description': 'HiSilicon', 171 'flags': [ 172 ['RTE_USE_C11_MEM_MODEL', true], 173 ['RTE_CACHE_LINE_SIZE', 128] 174 ], 175 'part_number_config': { 176 '0xd01': { 177 'march': 'armv8.2-a', 178 'march_features': ['crypto'], 179 'compiler_options': ['-mtune=tsv110'], 180 'flags': [ 181 ['RTE_MACHINE', '"Kunpeng 920"'], 182 ['RTE_ARM_FEATURE_ATOMICS', true], 183 ['RTE_MAX_LCORE', 256], 184 ['RTE_MAX_NUMA_NODES', 8] 185 ] 186 }, 187 '0xd02': { 188 'march': 'armv8.2-a', 189 'march_features': ['crypto', 'sve'], 190 'flags': [ 191 ['RTE_MACHINE', '"Kunpeng 930"'], 192 ['RTE_ARM_FEATURE_ATOMICS', true], 193 ['RTE_MAX_LCORE', 1280], 194 ['RTE_MAX_NUMA_NODES', 16] 195 ] 196 } 197 } 198} 199 200implementer_qualcomm = { 201 'description': 'Qualcomm', 202 'flags': [ 203 ['RTE_MACHINE', '"armv8a"'], 204 ['RTE_USE_C11_MEM_MODEL', true], 205 ['RTE_CACHE_LINE_SIZE', 64], 206 ['RTE_MAX_LCORE', 64], 207 ['RTE_MAX_NUMA_NODES', 1] 208 ], 209 'part_number_config': { 210 '0x800': { 211 'march': 'armv8-a', 212 'march_features': ['crc'] 213 }, 214 '0xc00': { 215 'march': 'armv8-a', 216 'march_features': ['crc'] 217 } 218 } 219} 220 221## Arm implementers (ID from MIDR in Arm Architecture Reference Manual) 222implementers = { 223 'generic': implementer_generic, 224 '0x41': implementer_arm, 225 '0x43': implementer_cavium, 226 '0x48': implementer_hisilicon, 227 '0x50': implementer_ampere, 228 '0x51': implementer_qualcomm 229} 230 231# SoC specific armv8 flags have the highest priority 232# (will overwrite all other flags) 233soc_generic = { 234 'description': 'Generic un-optimized build for armv8 aarch64 exec mode', 235 'implementer': 'generic', 236 'part_number': 'generic' 237} 238 239soc_generic_aarch32 = { 240 'description': 'Generic un-optimized build for armv8 aarch32 exec mode', 241 'implementer': 'generic', 242 'part_number': 'generic_aarch32' 243} 244 245soc_armada = { 246 'description': 'Marvell ARMADA', 247 'implementer': '0x41', 248 'part_number': '0xd08', 249 'flags': [ 250 ['RTE_MAX_LCORE', 16], 251 ['RTE_MAX_NUMA_NODES', 1] 252 ], 253 'numa': false 254} 255 256soc_bluefield = { 257 'description': 'NVIDIA BlueField', 258 'implementer': '0x41', 259 'part_number': '0xd08', 260 'flags': [ 261 ['RTE_MAX_LCORE', 16], 262 ['RTE_MAX_NUMA_NODES', 1] 263 ], 264 'numa': false 265} 266 267soc_centriq2400 = { 268 'description': 'Qualcomm Centriq 2400', 269 'implementer': '0x51', 270 'part_number': '0xc00', 271 'numa': false 272} 273 274soc_cn10k = { 275 'description' : 'Marvell OCTEON 10', 276 'implementer' : '0x41', 277 'flags': [ 278 ['RTE_MAX_LCORE', 24], 279 ['RTE_MAX_NUMA_NODES', 1], 280 ['RTE_MEMPOOL_ALIGN', 128] 281 ], 282 'part_number': '0xd49', 283 'extra_march_features': ['crypto'], 284 'numa': false 285} 286 287soc_dpaa = { 288 'description': 'NXP DPAA', 289 'implementer': '0x41', 290 'part_number': '0xd08', 291 'flags': [ 292 ['RTE_MACHINE', '"dpaa"'], 293 ['RTE_LIBRTE_DPAA2_USE_PHYS_IOVA', false], 294 ['RTE_MAX_LCORE', 16], 295 ['RTE_MAX_NUMA_NODES', 1] 296 ], 297 'numa': false 298} 299 300soc_emag = { 301 'description': 'Ampere eMAG', 302 'implementer': '0x50', 303 'part_number': '0x0' 304} 305 306soc_graviton2 = { 307 'description': 'AWS Graviton2', 308 'implementer': '0x41', 309 'part_number': '0xd0c', 310 'numa': false 311} 312 313soc_kunpeng920 = { 314 'description': 'HiSilicon Kunpeng 920', 315 'implementer': '0x48', 316 'part_number': '0xd01', 317 'numa': true 318} 319 320soc_kunpeng930 = { 321 'description': 'HiSilicon Kunpeng 930', 322 'implementer': '0x48', 323 'part_number': '0xd02', 324 'numa': true 325} 326 327soc_n1sdp = { 328 'description': 'Arm Neoverse N1SDP', 329 'implementer': '0x41', 330 'part_number': '0xd0c', 331 'flags': [ 332 ['RTE_MAX_LCORE', 4] 333 ], 334 'numa': false 335} 336 337soc_n2 = { 338 'description': 'Arm Neoverse N2', 339 'implementer': '0x41', 340 'part_number': '0xd49', 341 'numa': false 342} 343 344soc_cn9k = { 345 'description': 'Marvell OCTEON 9', 346 'implementer': '0x43', 347 'part_number': '0xb2', 348 'numa': false 349} 350 351soc_stingray = { 352 'description': 'Broadcom Stingray', 353 'implementer': '0x41', 354 'flags': [ 355 ['RTE_MAX_LCORE', 16], 356 ['RTE_MAX_NUMA_NODES', 1] 357 ], 358 'part_number': '0xd08', 359 'numa': false 360} 361 362soc_thunderx2 = { 363 'description': 'Marvell ThunderX2 T99', 364 'implementer': '0x43', 365 'part_number': '0xaf' 366} 367 368soc_thunderxt88 = { 369 'description': 'Marvell ThunderX T88', 370 'implementer': '0x43', 371 'part_number': '0xa1' 372} 373 374''' 375Start of SoCs list 376generic: Generic un-optimized build for armv8 aarch64 execution mode. 377generic_aarch32: Generic un-optimized build for armv8 aarch32 execution mode. 378armada: Marvell ARMADA 379bluefield: NVIDIA BlueField 380centriq2400: Qualcomm Centriq 2400 381cn9k: Marvell OCTEON 9 382cn10k: Marvell OCTEON 10 383dpaa: NXP DPAA 384emag: Ampere eMAG 385graviton2: AWS Graviton2 386kunpeng920: HiSilicon Kunpeng 920 387kunpeng930: HiSilicon Kunpeng 930 388n1sdp: Arm Neoverse N1SDP 389n2: Arm Neoverse N2 390stingray: Broadcom Stingray 391thunderx2: Marvell ThunderX2 T99 392thunderxt88: Marvell ThunderX T88 393End of SoCs list 394''' 395# The string above is included in the documentation, keep it in sync with the 396# SoCs list below. 397socs = { 398 'generic': soc_generic, 399 'generic_aarch32': soc_generic_aarch32, 400 'armada': soc_armada, 401 'bluefield': soc_bluefield, 402 'centriq2400': soc_centriq2400, 403 'cn9k': soc_cn9k, 404 'cn10k' : soc_cn10k, 405 'dpaa': soc_dpaa, 406 'emag': soc_emag, 407 'graviton2': soc_graviton2, 408 'kunpeng920': soc_kunpeng920, 409 'kunpeng930': soc_kunpeng930, 410 'n1sdp': soc_n1sdp, 411 'n2': soc_n2, 412 'stingray': soc_stingray, 413 'thunderx2': soc_thunderx2, 414 'thunderxt88': soc_thunderxt88 415} 416 417dpdk_conf.set('RTE_ARCH_ARM', 1) 418dpdk_conf.set('RTE_FORCE_INTRINSICS', 1) 419 420update_flags = false 421soc_flags = [] 422if dpdk_conf.get('RTE_ARCH_32') 423 # 32-bit build 424 dpdk_conf.set('RTE_CACHE_LINE_SIZE', 64) 425 if meson.is_cross_build() 426 update_flags = true 427 soc = meson.get_cross_property('platform', '') 428 if soc == '' 429 error('Arm SoC must be specified in the cross file.') 430 endif 431 soc_config = socs.get(soc, {'not_supported': true}) 432 flags_common = [] 433 else 434 # armv7 build 435 dpdk_conf.set('RTE_ARCH_ARMv7', true) 436 dpdk_conf.set('RTE_ARCH', 'armv7') 437 dpdk_conf.set('RTE_MAX_LCORE', 128) 438 dpdk_conf.set('RTE_MAX_NUMA_NODES', 1) 439 # the minimum architecture supported, armv7-a, needs the following, 440 machine_args += '-mfpu=neon' 441 endif 442else 443 # armv8 build 444 dpdk_conf.set('RTE_ARCH', 'armv8') 445 update_flags = true 446 soc_config = {} 447 if not meson.is_cross_build() 448 # for backwards compatibility: 449 # machine=native is the same behavior as soc=native 450 # machine=generic/default is the same as soc=generic 451 # cpu_instruction_set holds the proper value - native, generic or cpu 452 # the old behavior only distinguished between generic and native build 453 if machine != 'auto' 454 if cpu_instruction_set == 'generic' 455 soc = 'generic' 456 else 457 soc = 'native' 458 endif 459 else 460 soc = platform 461 endif 462 if soc == 'native' 463 # native build 464 # The script returns ['Implementer', 'Variant', 'Architecture', 465 # 'Primary Part number', 'Revision'] 466 detect_vendor = find_program(join_paths(meson.current_source_dir(), 467 'armv8_machine.py')) 468 cmd = run_command(detect_vendor.path(), check: false) 469 if cmd.returncode() == 0 470 cmd_output = cmd.stdout().to_lower().strip().split(' ') 471 implementer_id = cmd_output[0] 472 part_number = cmd_output[3] 473 else 474 error('Error when getting Arm Implementer ID and part number.') 475 endif 476 else 477 # SoC build 478 soc_config = socs.get(soc, {'not_supported': true}) 479 endif 480 else 481 # cross build 482 soc = meson.get_cross_property('platform', '') 483 if soc == '' 484 error('Arm SoC must be specified in the cross file.') 485 endif 486 soc_config = socs.get(soc, {'not_supported': true}) 487 endif 488endif 489 490if update_flags 491 if soc_config.has_key('not_supported') 492 error('SoC @0@ not supported.'.format(soc)) 493 elif soc_config != {} 494 implementer_id = soc_config['implementer'] 495 implementer_config = implementers[implementer_id] 496 part_number = soc_config['part_number'] 497 soc_flags = soc_config.get('flags', []) 498 if not soc_config.get('numa', true) 499 has_libnuma = 0 500 endif 501 502 disable_drivers += ',' + soc_config.get('disable_drivers', '') 503 enable_drivers += ',' + soc_config.get('enable_drivers', '') 504 endif 505 506 if implementers.has_key(implementer_id) 507 implementer_config = implementers[implementer_id] 508 else 509 error('Unsupported Arm implementer: @0@. '.format(implementer_id) + 510 'Please add support for it or use the generic ' + 511 '(-Dplatform=generic) build.') 512 endif 513 514 message('Arm implementer: ' + implementer_config['description']) 515 message('Arm part number: ' + part_number) 516 517 part_number_config = implementer_config['part_number_config'] 518 if part_number_config.has_key(part_number) 519 # use the specified part_number machine args if found 520 part_number_config = part_number_config[part_number] 521 else 522 # unknown part number 523 error('Unsupported part number @0@ of implementer @1@. ' 524 .format(part_number, implementer_id) + 525 'Please add support for it or use the generic ' + 526 '(-Dplatform=generic) build.') 527 endif 528 529 # add/overwrite flags in the proper order 530 dpdk_flags = flags_common + implementer_config['flags'] + part_number_config.get('flags', []) + soc_flags 531 532 machine_args = [] # Clear previous machine args 533 534 # probe supported archs and their features 535 candidate_march = '' 536 if part_number_config.has_key('march') 537 supported_marchs = ['armv8.6-a', 'armv8.5-a', 'armv8.4-a', 'armv8.3-a', 538 'armv8.2-a', 'armv8.1-a', 'armv8-a'] 539 check_compiler_support = false 540 foreach supported_march: supported_marchs 541 if supported_march == part_number_config['march'] 542 # start checking from this version downwards 543 check_compiler_support = true 544 endif 545 if (check_compiler_support and 546 cc.has_argument('-march=' + supported_march)) 547 candidate_march = supported_march 548 # highest supported march version found 549 break 550 endif 551 endforeach 552 if candidate_march == '' 553 error('No suitable armv8 march version found.') 554 endif 555 if candidate_march != part_number_config['march'] 556 warning('Configuration march version is ' + 557 '@0@, but the compiler supports only @1@.' 558 .format(part_number_config['march'], candidate_march)) 559 endif 560 candidate_march = '-march=' + candidate_march 561 562 march_features = [] 563 if part_number_config.has_key('march_features') 564 march_features += part_number_config['march_features'] 565 endif 566 if soc_config.has_key('extra_march_features') 567 march_features += soc_config['extra_march_features'] 568 endif 569 foreach feature: march_features 570 if cc.has_argument('+'.join([candidate_march, feature])) 571 candidate_march = '+'.join([candidate_march, feature]) 572 else 573 warning('The compiler does not support feature @0@' 574 .format(feature)) 575 endif 576 endforeach 577 machine_args += candidate_march 578 endif 579 580 # apply supported compiler options 581 if part_number_config.has_key('compiler_options') 582 foreach flag: part_number_config['compiler_options'] 583 if cc.has_argument(flag) 584 machine_args += flag 585 else 586 warning('Configuration compiler option ' + 587 '@0@ isn\'t supported.'.format(flag)) 588 endif 589 endforeach 590 endif 591 592 # apply flags 593 foreach flag: dpdk_flags 594 if flag.length() > 0 595 dpdk_conf.set(flag[0], flag[1]) 596 endif 597 endforeach 598endif 599message('Using machine args: @0@'.format(machine_args)) 600 601if (cc.get_define('__ARM_NEON', args: machine_args) != '' or 602 cc.get_define('__aarch64__', args: machine_args) != '') 603 compile_time_cpuflags += ['RTE_CPUFLAG_NEON'] 604endif 605 606if cc.get_define('__ARM_FEATURE_SVE', args: machine_args) != '' 607 compile_time_cpuflags += ['RTE_CPUFLAG_SVE'] 608 if (cc.check_header('arm_sve.h')) 609 dpdk_conf.set('RTE_HAS_SVE_ACLE', 1) 610 endif 611endif 612 613if cc.get_define('__ARM_FEATURE_CRC32', args: machine_args) != '' 614 compile_time_cpuflags += ['RTE_CPUFLAG_CRC32'] 615endif 616 617if cc.get_define('__ARM_FEATURE_CRYPTO', args: machine_args) != '' 618 compile_time_cpuflags += ['RTE_CPUFLAG_AES', 'RTE_CPUFLAG_PMULL', 619 'RTE_CPUFLAG_SHA1', 'RTE_CPUFLAG_SHA2'] 620endif 621