Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
authorMark Brown <broonie@linaro.org>
Tue, 20 May 2014 00:02:49 +0000 (01:02 +0100)
committerMark Brown <broonie@linaro.org>
Tue, 20 May 2014 00:02:49 +0000 (01:02 +0100)
arch/arm64/include/asm/arch_timer.h
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/hwcap.h
arch/arm64/include/uapi/asm/hwcap.h
arch/arm64/kernel/head.S
arch/arm64/kernel/setup.c
arch/arm64/kernel/vmlinux.lds.S

index cb2be3b86c6bd85f2d042341c25e86d1aae2a48d..2bff16df74a47a88527c0146becf7799ce664072 100644 (file)
@@ -140,6 +140,37 @@ static inline void arch_timer_evtstrm_enable(int divider)
 #endif
 }
 
+static inline u64 arch_counter_get_cntpct(void)
+{
+       u32 cntkctl = arch_timer_get_cntkctl();
+
+       /* Disable user access to the timers and the physical counter */
+       /* Also disable virtual event stream */
+       cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
+                       | ARCH_TIMER_USR_VT_ACCESS_EN
+                       | ARCH_TIMER_VIRT_EVT_EN
+                       | ARCH_TIMER_USR_PCT_ACCESS_EN);
+
+       /* Enable user access to the virtual counter */
+       cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+
+       arch_timer_set_cntkctl(cntkctl);
+}
+
+static inline void arch_timer_evtstrm_enable(int divider)
+{
+       u32 cntkctl = arch_timer_get_cntkctl();
+       cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
+       /* Set the divider and enable virtual event stream */
+       cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
+                       | ARCH_TIMER_VIRT_EVT_EN;
+       arch_timer_set_cntkctl(cntkctl);
+       elf_hwcap |= HWCAP_EVTSTRM;
+#ifdef CONFIG_COMPAT
+       compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
+#endif
+}
+
 static inline u64 arch_counter_get_cntvct(void)
 {
        u64 cval;
index e371936b8ab2ed2a66a73a3f148af16bba50a40b..c404fb0df3a673710285603c8ba7571fa42a86f8 100644 (file)
 #ifndef __ASM_CPUTYPE_H
 #define __ASM_CPUTYPE_H
 
-#define ID_MIDR_EL1            "midr_el1"
-#define ID_MPIDR_EL1           "mpidr_el1"
-#define ID_CTR_EL0             "ctr_el0"
-
-#define ID_AA64PFR0_EL1                "id_aa64pfr0_el1"
-#define ID_AA64DFR0_EL1                "id_aa64dfr0_el1"
-#define ID_AA64AFR0_EL1                "id_aa64afr0_el1"
-#define ID_AA64ISAR0_EL1       "id_aa64isar0_el1"
-#define ID_AA64MMFR0_EL1       "id_aa64mmfr0_el1"
-
 #define INVALID_HWID           ULONG_MAX
 
 #define MPIDR_HWID_BITMASK     0xff00ffffff
@@ -42,7 +32,7 @@
 
 #define read_cpuid(reg) ({                                             \
        u64 __val;                                                      \
-       asm("mrs        %0, " reg : "=r" (__val));                      \
+       asm("mrs        %0, " #reg : "=r" (__val));                     \
        __val;                                                          \
 })
 
  */
 static inline u32 __attribute_const__ read_cpuid_id(void)
 {
-       return read_cpuid(ID_MIDR_EL1);
+       return read_cpuid(MIDR_EL1);
 }
 
 static inline u64 __attribute_const__ read_cpuid_mpidr(void)
 {
-       return read_cpuid(ID_MPIDR_EL1);
+       return read_cpuid(MPIDR_EL1);
 }
 
 static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
@@ -84,7 +74,7 @@ static inline unsigned int __attribute_const__ read_cpuid_part_number(void)
 
 static inline u32 __attribute_const__ read_cpuid_cachetype(void)
 {
-       return read_cpuid(ID_CTR_EL0);
+       return read_cpuid(CTR_EL0);
 }
 
 #endif /* __ASSEMBLY__ */
index 6cddbb0c9f5459cff851101fd3010ad74882a1ef..024c46183c3cc4bac07977ffcdade60c2567ea98 100644 (file)
 #define COMPAT_HWCAP_IDIV      (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
 #define COMPAT_HWCAP_EVTSTRM   (1 << 21)
 
+#define COMPAT_HWCAP2_AES      (1 << 0)
+#define COMPAT_HWCAP2_PMULL    (1 << 1)
+#define COMPAT_HWCAP2_SHA1     (1 << 2)
+#define COMPAT_HWCAP2_SHA2     (1 << 3)
+#define COMPAT_HWCAP2_CRC32    (1 << 4)
+
 #ifndef __ASSEMBLY__
 /*
  * This yields a mask that user programs can use to figure out what
@@ -41,7 +47,8 @@
 
 #ifdef CONFIG_COMPAT
 #define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
-extern unsigned int compat_elf_hwcap;
+#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
+extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
 #endif
 
 extern unsigned long elf_hwcap;
index 9b12476e9c8567545c493704075f56c8643bbae6..73cf0f54d57cc2459ce424f627f2a15d2ac496e6 100644 (file)
 #define HWCAP_FP               (1 << 0)
 #define HWCAP_ASIMD            (1 << 1)
 #define HWCAP_EVTSTRM          (1 << 2)
-
+#define HWCAP_AES              (1 << 3)
+#define HWCAP_PMULL            (1 << 4)
+#define HWCAP_SHA1             (1 << 5)
+#define HWCAP_SHA2             (1 << 6)
+#define HWCAP_CRC32            (1 << 7)
 
 #endif /* _UAPI__ASM_HWCAP_H */
index 7009387348b7c416f9dc8732a18c7563eac4af4e..41cceeb83a482a8ac323e835b678a4eea951432f 100644 (file)
@@ -481,8 +481,6 @@ ENDPROC(__create_page_tables)
        .type   __switch_data, %object
 __switch_data:
        .quad   __mmap_switched
-       .quad   __data_loc                      // x4
-       .quad   _data                           // x5
        .quad   __bss_start                     // x6
        .quad   _end                            // x7
        .quad   processor_id                    // x4
@@ -497,15 +495,7 @@ __switch_data:
 __mmap_switched:
        adr     x3, __switch_data + 8
 
-       ldp     x4, x5, [x3], #16
        ldp     x6, x7, [x3], #16
-       cmp     x4, x5                          // Copy data segment if needed
-1:     ccmp    x5, x6, #4, ne
-       b.eq    2f
-       ldr     x16, [x4], #8
-       str     x16, [x5], #8
-       b       1b
-2:
 1:     cmp     x6, x7
        b.hs    2f
        str     xzr, [x6], #8                   // Clear BSS
index 8c7e81c0143faffe664c94b96c972f944641edd5..bb9e709879c350434fc9a157c4e2e09c3d5c7881 100644 (file)
@@ -69,6 +69,7 @@ EXPORT_SYMBOL_GPL(elf_hwcap);
                                 COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
                                 COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)
 unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
+unsigned int compat_elf_hwcap2 __read_mostly;
 #endif
 
 static const char *cpu_name;
@@ -195,12 +196,8 @@ static void __init smp_build_mpidr_hash(void)
 static void __init setup_processor(void)
 {
        struct cpu_info *cpu_info;
+       u64 features, block;
 
-       /*
-        * locate processor in the list of supported processor
-        * types.  The linker builds this table for us from the
-        * entries in arch/arm/mm/proc.S
-        */
        cpu_info = lookup_processor_type(read_cpuid_id());
        if (!cpu_info) {
                printk("CPU configuration botched (ID %08x), unable to continue.\n",
@@ -215,6 +212,69 @@ static void __init setup_processor(void)
 
        sprintf(init_utsname()->machine, ELF_PLATFORM);
        elf_hwcap = 0;
+
+       /*
+        * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks.
+        * The blocks we test below represent incremental functionality
+        * for non-negative values. Negative values are reserved.
+        */
+       features = read_cpuid(ID_AA64ISAR0_EL1);
+       block = (features >> 4) & 0xf;
+       if (!(block & 0x8)) {
+               switch (block) {
+               default:
+               case 2:
+                       elf_hwcap |= HWCAP_PMULL;
+               case 1:
+                       elf_hwcap |= HWCAP_AES;
+               case 0:
+                       break;
+               }
+       }
+
+       block = (features >> 8) & 0xf;
+       if (block && !(block & 0x8))
+               elf_hwcap |= HWCAP_SHA1;
+
+       block = (features >> 12) & 0xf;
+       if (block && !(block & 0x8))
+               elf_hwcap |= HWCAP_SHA2;
+
+       block = (features >> 16) & 0xf;
+       if (block && !(block & 0x8))
+               elf_hwcap |= HWCAP_CRC32;
+
+#ifdef CONFIG_COMPAT
+       /*
+        * ID_ISAR5_EL1 carries similar information as above, but pertaining to
+        * the Aarch32 32-bit execution state.
+        */
+       features = read_cpuid(ID_ISAR5_EL1);
+       block = (features >> 4) & 0xf;
+       if (!(block & 0x8)) {
+               switch (block) {
+               default:
+               case 2:
+                       compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
+               case 1:
+                       compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
+               case 0:
+                       break;
+               }
+       }
+
+       block = (features >> 8) & 0xf;
+       if (block && !(block & 0x8))
+               compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
+
+       block = (features >> 12) & 0xf;
+       if (block && !(block & 0x8))
+               compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
+
+       block = (features >> 16) & 0xf;
+       if (block && !(block & 0x8))
+               compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
+#endif
 }
 
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
@@ -407,6 +467,11 @@ static const char *hwcap_str[] = {
        "fp",
        "asimd",
        "evtstrm",
+       "aes",
+       "pmull",
+       "sha1",
+       "sha2",
+       "crc32",
        NULL
 };
 
index af46c8e13737ea70325bf8bf6efc1bda19c0aaf3..18a08e10357f2f2e2529210e78f2cb2f8afd76bc 100644 (file)
@@ -85,11 +85,9 @@ SECTIONS
 
        . = ALIGN(PAGE_SIZE);
        _data = .;
-       __data_loc = _data - LOAD_OFFSET;
        _sdata = .;
        RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
        _edata = .;
-       _edata_loc = __data_loc + SIZEOF(.data);
 
        BSS_SECTION(0, 0, 0)
        _end = .;