aarch64: Add Linux runtime cpu feature detection using HWCAP_CPUID
Based partially on code by Janne Grunau. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
		
							parent
							
								
									397cb623c8
								
							
						
					
					
						commit
						493fcde50a
					
				
							
								
								
									
										2
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@ -2209,6 +2209,7 @@ HAVE_LIST_PUB="
 | 
			
		||||
 | 
			
		||||
HEADERS_LIST="
 | 
			
		||||
    arpa_inet_h
 | 
			
		||||
    asm_hwcap_h
 | 
			
		||||
    asm_types_h
 | 
			
		||||
    cdio_paranoia_h
 | 
			
		||||
    cdio_paranoia_paranoia_h
 | 
			
		||||
@ -6432,6 +6433,7 @@ check_headers io.h
 | 
			
		||||
enabled libdrm &&
 | 
			
		||||
    check_headers linux/dma-buf.h
 | 
			
		||||
 | 
			
		||||
check_headers asm/hwcap.h
 | 
			
		||||
check_headers linux/perf_event.h
 | 
			
		||||
check_headers libcrystalhd/libcrystalhd_if.h
 | 
			
		||||
check_headers malloc.h
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,56 @@
 | 
			
		||||
#include "libavutil/cpu_internal.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#if (defined(__linux__) || defined(__ANDROID__)) && HAVE_GETAUXVAL && HAVE_ASM_HWCAP_H
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <asm/hwcap.h>
 | 
			
		||||
#include <sys/auxv.h>
 | 
			
		||||
 | 
			
		||||
#define get_cpu_feature_reg(reg, val) \
 | 
			
		||||
        __asm__("mrs %0, " #reg : "=r" (val))
 | 
			
		||||
 | 
			
		||||
static int detect_flags(void)
 | 
			
		||||
{
 | 
			
		||||
    int flags = 0;
 | 
			
		||||
    unsigned long hwcap;
 | 
			
		||||
 | 
			
		||||
    hwcap = getauxval(AT_HWCAP);
 | 
			
		||||
 | 
			
		||||
#if defined(HWCAP_CPUID)
 | 
			
		||||
    // We can check for DOTPROD and I8MM using HWCAP_ASIMDDP and
 | 
			
		||||
    // HWCAP2_I8MM too, avoiding to read the CPUID registers (which triggers
 | 
			
		||||
    // a trap, handled by the kernel). However the HWCAP_* defines for these
 | 
			
		||||
    // extensions are added much later than HWCAP_CPUID, so the userland
 | 
			
		||||
    // headers might lack support for them even if the binary later is run
 | 
			
		||||
    // on hardware that does support it (and where the kernel might support
 | 
			
		||||
    // HWCAP_CPUID).
 | 
			
		||||
    // See https://www.kernel.org/doc/html/latest/arm64/cpu-feature-registers.html
 | 
			
		||||
    if (hwcap & HWCAP_CPUID) {
 | 
			
		||||
        uint64_t tmp;
 | 
			
		||||
 | 
			
		||||
        get_cpu_feature_reg(ID_AA64ISAR0_EL1, tmp);
 | 
			
		||||
        if (((tmp >> 44) & 0xf) == 0x1)
 | 
			
		||||
            flags |= AV_CPU_FLAG_DOTPROD;
 | 
			
		||||
        get_cpu_feature_reg(ID_AA64ISAR1_EL1, tmp);
 | 
			
		||||
        if (((tmp >> 52) & 0xf) == 0x1)
 | 
			
		||||
            flags |= AV_CPU_FLAG_I8MM;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    (void)hwcap;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
static int detect_flags(void)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int ff_get_cpu_flags_aarch64(void)
 | 
			
		||||
{
 | 
			
		||||
    int flags = AV_CPU_FLAG_ARMV8 * HAVE_ARMV8 |
 | 
			
		||||
@ -33,6 +83,8 @@ int ff_get_cpu_flags_aarch64(void)
 | 
			
		||||
    flags |= AV_CPU_FLAG_I8MM;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    flags |= detect_flags();
 | 
			
		||||
 | 
			
		||||
    return flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user