xref: /dpdk/config/arm/meson.build (revision 3cba7ced)
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