diff options
| -rw-r--r-- | src/pulsecore/cpu-arm.c | 107 | ||||
| -rw-r--r-- | src/pulsecore/cpu-arm.h | 7 | 
2 files changed, 107 insertions, 7 deletions
diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c index 75646fe4..93ad3891 100644 --- a/src/pulsecore/cpu-arm.c +++ b/src/pulsecore/cpu-arm.c @@ -25,19 +25,116 @@  #endif  #include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <pulse/xmalloc.h>  #include <pulsecore/log.h>  #include "cpu-arm.h" -static pa_cpu_arm_flag_t pa_cpu_arm_flags; +#if defined (__arm__) && defined (__linux__) + +#define MAX_BUFFER	4096 +static char * +get_cpuinfo_line (char *cpuinfo, const char *tag) { +    char *line, *end, *colon; + +    if (!(line = strstr (cpuinfo, tag))) +        return NULL; +      +    if (!(end = strchr (line, '\n'))) +        return NULL; + +    if (!(colon = strchr (line, ':'))) +        return NULL; + +    if (++colon >= end) +        return NULL; + +    return pa_xstrndup (colon, end - colon); +} + +static char *get_cpuinfo(void) { +    char *cpuinfo; +    int n, fd; + +    if (!(cpuinfo = malloc(MAX_BUFFER))) +         return NULL; + +    if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) { +        free (cpuinfo); +        return NULL; +    } + +    if ((n = read(fd, cpuinfo, MAX_BUFFER-1)) < 0) { +        free (cpuinfo); +        close (fd); +        return NULL; +    } +    cpuinfo[n] = 0; +    close (fd); + +    return cpuinfo; +} +#endif /* defined (__arm__) && defined (__linux__) */  void pa_cpu_init_arm (void) {  #if defined (__arm__) -    pa_cpu_arm_flags = 0; -    -    pa_log ("ARM init\n"); +#if defined (__linux__) +    char *cpuinfo, *line; +    int arch; +    pa_cpu_arm_flag_t flags = 0; + +    /* We need to read the CPU flags from /proc/cpuinfo because there is no user +     * space support to get the CPU features. This only works on linux AFAIK. */ +    if (!(cpuinfo = get_cpuinfo ())) { +        pa_log ("Can't read cpuinfo"); +        return; +    } + +    /* get the CPU architecture */ +    if ((line = get_cpuinfo_line (cpuinfo, "CPU architecture"))) { +        arch = strtoul (line, NULL, 0); +        if (arch >= 6) +            flags |= PA_CPU_ARM_V6; +        if (arch >= 7) +            flags |= PA_CPU_ARM_V7; + +        free (line); +    } +    /* get the CPU features */ +    if ((line = get_cpuinfo_line (cpuinfo, "Features"))) { +	  char *state = NULL, *current; + +	  while ((current = pa_split_spaces (line, &state))) { +              if (!strcmp (current, "vfp"))  +                  flags |= PA_CPU_ARM_VFP; +	      else if (!strcmp (current, "edsp"))  +                  flags |= PA_CPU_ARM_EDSP; +	      else if (!strcmp (current, "neon"))  +                  flags |= PA_CPU_ARM_NEON; +	      else if (!strcmp (current, "vfpv3"))  +                  flags |= PA_CPU_ARM_VFPV3; + +              free (current); +	  } +    } +    free (cpuinfo); + +    pa_log_info ("CPU flags: %s%s%s%s%s%s", +          (flags & PA_CPU_ARM_V6) ? "V6 " : "", +          (flags & PA_CPU_ARM_V7) ? "V7 " : "", +          (flags & PA_CPU_ARM_VFP) ? "VFP " : "", +          (flags & PA_CPU_ARM_EDSP) ? "EDSP " : "", +          (flags & PA_CPU_ARM_NEON) ? "NEON " : "", +          (flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : ""); +#else /* defined (__linux__) */ +    pa_log ("ARM cpu features not yet supported on this OS"); +#endif /* defined (__linux__) */ -    pa_volume_func_init_arm (pa_cpu_arm_flags); +    if (flags & PA_CPU_ARM_V6) +        pa_volume_func_init_arm (flags);  #endif /* defined (__arm__) */  } diff --git a/src/pulsecore/cpu-arm.h b/src/pulsecore/cpu-arm.h index 1a0ac273..3ccd0708 100644 --- a/src/pulsecore/cpu-arm.h +++ b/src/pulsecore/cpu-arm.h @@ -27,8 +27,11 @@  typedef enum pa_cpu_arm_flag {      PA_CPU_ARM_V6       = (1 << 0), -    PA_CPU_ARM_NEON     = (1 << 1), -    PA_CPU_ARM_VFP      = (1 << 2) +    PA_CPU_ARM_V7       = (1 << 1), +    PA_CPU_ARM_VFP      = (1 << 2), +    PA_CPU_ARM_EDSP     = (1 << 3), +    PA_CPU_ARM_NEON     = (1 << 4), +    PA_CPU_ARM_VFPV3    = (1 << 5)  } pa_cpu_arm_flag_t;  void pa_cpu_init_arm (void);  | 
