Esempio n. 1
0
static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) {
  if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) {
    /* This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always
     * available on ARMv8. Linux omits required features, so reading the
     * "Features" line does not work. (For simplicity, use strict equality. We
     * assume everything running on future ARM architectures will have a
     * working |getauxval|.) */
    return HWCAP_NEON;
  }

  STRING_PIECE features;
  if (extract_cpuinfo_field(&features, cpuinfo, "Features") &&
      has_list_item(&features, "neon")) {
    return HWCAP_NEON;
  }
  return 0;
}
Esempio n. 2
0
static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) {
  STRING_PIECE features;
  if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) {
    return 0;
  }

  unsigned long ret = 0;
  if (has_list_item(&features, "aes")) {
    ret |= HWCAP2_AES;
  }
  if (has_list_item(&features, "pmull")) {
    ret |= HWCAP2_PMULL;
  }
  if (has_list_item(&features, "sha1")) {
    ret |= HWCAP2_SHA1;
  }
  if (has_list_item(&features, "sha2")) {
    ret |= HWCAP2_SHA2;
  }
  return ret;
}
Esempio n. 3
0
static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field,
                                const char *value) {
  STRING_PIECE extracted;
  return extract_cpuinfo_field(&extracted, cpuinfo, field) &&
         STRING_PIECE_equals(&extracted, value);
}
Esempio n. 4
0
static void
android_cpuInit(void)
{
    char cpuinfo[4096];
    int  cpuinfo_len;

    g_cpuFamily   = DEFAULT_CPU_FAMILY;
    g_cpuFeatures = 0;
    g_cpuCount    = 1;

    cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
    D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
      cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);

    if (cpuinfo_len < 0)  /* should not happen */ {
        return;
    }

    /* Count the CPU cores, the value may be 0 for single-core CPUs */
    g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "processor");
    if (g_cpuCount == 0) {
        g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "Processor");
        if (g_cpuCount == 0) {
            g_cpuCount = 1;
        }
    }

    D("found cpuCount = %d\n", g_cpuCount);

#ifdef __arm__
    {
        char*  features = NULL;
        char*  architecture = NULL;
        /* Extract architecture from the "CPU Architecture" field.
         * The list is well-known, unlike the the output of
         * the 'Processor' field which can vary greatly.
         *
         * See the definition of the 'proc_arch' array in
         * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
         * same file.
         */
        char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");

        if (cpuArch != NULL) {
            char*  end;
            long   archNumber;
            int    hasARMv7 = 0;
            int    hasARMv6 = 0;

            D("found cpuArch = '%s'\n", cpuArch);

            /* read the initial decimal number, ignore the rest */
            archNumber = strtol(cpuArch, &end, 10);

            D("found archNumber = '%d'\n", archNumber);

            /* Here we assume that ARMv8 will be upwards compatible with v7
                * in the future. Unfortunately, there is no 'Features' field to
                * indicate that Thumb-2 is supported.
                */
            if (end > cpuArch ){
            	if (archNumber >= 7) {
            		hasARMv7 = 1;
            	}
            	else if (archNumber == 6) {
            		g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv6;
            	}
            	else
            	{
            		g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv5TE;
            	}
            }
            else{
                    g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv5TE;
            }

            /* Unfortunately, it seems that certain ARMv6-based CPUs
             * report an incorrect architecture number of 7!
             *
             * See http://code.google.com/p/android/issues/detail?id=10812
             *
             * We try to correct this by looking at the 'elf_format'
             * field reported by the 'Processor' field, which is of the
             * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
             * an ARMv6-one.
             */
            if (hasARMv7) {
                char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
                                                      "Processor");
                if (cpuProc != NULL) {
                    D("found cpuProc = '%s'\n", cpuProc);
                    if (has_list_item(cpuProc, "(v6l)")) {
                        D("CPU processor and architecture mismatch!!\n");
                        hasARMv7 = 0;
                        g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv6;
                    }
                    free(cpuProc);
                }
            }

            if (hasARMv7) {
                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
            }

            /* The LDREX / STREX instructions are available from ARMv6 */
            if (archNumber >= 6) {
                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
            }

            free(cpuArch);
        }

        /* Extract the list of CPU features from 'Features' field */
        char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");

        if (cpuFeatures != NULL) {

            D("found cpuFeatures = '%s'\n", cpuFeatures);

            if (has_list_item(cpuFeatures, "vfpv3"))
                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;

            else if (has_list_item(cpuFeatures, "vfpv3d16"))
                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;

            if (has_list_item(cpuFeatures, "neon")) {
                /* Note: Certain kernels only report neon but not vfpv3
                    *       in their features list. However, ARM mandates
                    *       that if Neon is implemented, so must be VFPv3
                    *       so always set the flag.
                    */
                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON |
                                 ANDROID_CPU_ARM_FEATURE_VFPv3;
            }

            if (has_list_item(cpuFeatures, "vfp")){
            	g_cpuFeatures |=ANDROID_CPU_ARM_FEATURE_VFP;
            }

            free(cpuFeatures);
        }
    }
#endif /* __arm__ */

#ifdef __i386__
    g_cpuFamily = ANDROID_CPU_FAMILY_X86;
#endif
}