Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / kernel / setup.c
index e87b5fd07b8c3e4e5c2cba3c2bdfab3a30df29a6..3d0b5a285061a1feb081b5ee4b9f2df92bce376c 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 #include <linux/efi.h>
+#include <linux/personality.h>
 
 #include <asm/fixmap.h>
 #include <asm/cputype.h>
@@ -112,6 +113,19 @@ void __init early_print(const char *str, ...)
        printk("%s", buf);
 }
 
+struct cpuinfo_arm64 {
+       struct cpu      cpu;
+       u32             reg_midr;
+};
+
+static DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
+
+void cpuinfo_store_cpu(void)
+{
+       struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
+       info->reg_midr = read_cpuid_id();
+}
+
 void __init smp_setup_processor_id(void)
 {
        /*
@@ -285,6 +299,8 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
        struct boot_param_header *devtree;
        unsigned long dt_root;
 
+       cpuinfo_store_cpu();
+
        /* Check we have a non-NULL DT pointer */
        if (!dt_phys) {
                early_print("\n"
@@ -353,25 +369,6 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
        return __va(memblock_alloc(size, align));
 }
 
-/*
- * Limit the memory size that was specified via FDT.
- */
-static int __init early_mem(char *p)
-{
-       phys_addr_t limit;
-
-       if (!p)
-               return 1;
-
-       limit = memparse(p, &p) & PAGE_MASK;
-       pr_notice("Memory limited to %lldMB\n", limit >> 20);
-
-       memblock_enforce_memory_limit(limit);
-
-       return 0;
-}
-early_param("mem", early_mem);
-
 static void __init request_standard_resources(void)
 {
        struct memblock_region *region;
@@ -455,14 +452,12 @@ static int __init arm64_device_init(void)
 }
 arch_initcall_sync(arm64_device_init);
 
-static DEFINE_PER_CPU(struct cpu, cpu_data);
-
 static int __init topology_init(void)
 {
        int i;
 
        for_each_possible_cpu(i) {
-               struct cpu *cpu = &per_cpu(cpu_data, i);
+               struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
                cpu->hotpluggable = 1;
                register_cpu(cpu, i);
        }
@@ -483,14 +478,41 @@ static const char *hwcap_str[] = {
        NULL
 };
 
+#ifdef CONFIG_COMPAT
+static const char *compat_hwcap_str[] = {
+       "swp",
+       "half",
+       "thumb",
+       "26bit",
+       "fastmult",
+       "fpa",
+       "vfp",
+       "edsp",
+       "java",
+       "iwmmxt",
+       "crunch",
+       "thumbee",
+       "neon",
+       "vfpv3",
+       "vfpv3d16",
+       "tls",
+       "vfpv4",
+       "idiva",
+       "idivt",
+       "vfpd32",
+       "lpae",
+       "evtstrm"
+};
+#endif /* CONFIG_COMPAT */
+
 static int c_show(struct seq_file *m, void *v)
 {
-       int i;
-
-       seq_printf(m, "Processor\t: %s rev %d (%s)\n",
-                  cpu_name, read_cpuid_id() & 15, ELF_PLATFORM);
+       int i, j;
 
        for_each_online_cpu(i) {
+               struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+               u32 midr = cpuinfo->reg_midr;
+
                /*
                 * glibc reads /proc/cpuinfo to determine the number of
                 * online processors, looking for lines beginning with
@@ -499,24 +521,41 @@ static int c_show(struct seq_file *m, void *v)
 #ifdef CONFIG_SMP
                seq_printf(m, "processor\t: %d\n", i);
 #endif
-       }
 
-       /* dump out the processor features */
-       seq_puts(m, "Features\t: ");
+               seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+                          loops_per_jiffy / (500000UL/HZ),
+                          loops_per_jiffy / (5000UL/HZ) % 100);
 
-       for (i = 0; hwcap_str[i]; i++)
-               if (elf_hwcap & (1 << i))
-                       seq_printf(m, "%s ", hwcap_str[i]);
-
-       seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
-       seq_printf(m, "CPU architecture: AArch64\n");
-       seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
-       seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
-       seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
-
-       seq_puts(m, "\n");
+               /*
+                * Dump out the common processor features in a single line.
+                * Userspace should read the hwcaps with getauxval(AT_HWCAP)
+                * rather than attempting to parse this, but there's a body of
+                * software which does already (at least for 32-bit).
+                */
+               seq_puts(m, "Features\t:");
+               if (personality(current->personality) == PER_LINUX32) {
+#ifdef CONFIG_COMPAT
+                       for (j = 0; compat_hwcap_str[j]; j++)
+                               if (COMPAT_ELF_HWCAP & (1 << j))
+                                       seq_printf(m, " %s", compat_hwcap_str[j]);
+#endif /* CONFIG_COMPAT */
+               } else {
+                       for (j = 0; hwcap_str[j]; j++)
+                               if (elf_hwcap & (1 << j))
+                                       seq_printf(m, " %s", hwcap_str[j]);
+               }
+               seq_puts(m, "\n");
 
-       seq_printf(m, "Hardware\t: %s\n", machine_name);
+               seq_printf(m, "CPU implementer\t: 0x%02x\n", (midr >> 24));
+               seq_printf(m, "CPU architecture: %s\n",
+#if IS_ENABLED(CONFIG_ARMV7_COMPAT_CPUINFO)
+                               is_compat_task() ? "8" :
+#endif
+                               "AArch64");
+               seq_printf(m, "CPU variant\t: 0x%x\n", ((midr >> 20) & 0xf));
+               seq_printf(m, "CPU part\t: 0x%03x\n", ((midr >> 4) & 0xfff));
+               seq_printf(m, "CPU revision\t: %d\n\n", (midr & 0xf));
+       }
 
        return 0;
 }